• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

CityOfZion / neo3-boa / 858f5658-b835-4f01-86b4-3a69cebd0b86

16 Oct 2023 06:23PM UTC coverage: 91.625% (+0.004%) from 91.621%
858f5658-b835-4f01-86b4-3a69cebd0b86

push

circleci

Mirella de Medeiros
Bump version: 1.0.1 → 1.1.0

1 of 1 new or added line in 1 file covered. (100.0%)

19988 of 21815 relevant lines covered (91.63%)

0.92 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

87.64
/boa3/internal/model/builtin/classmethod/indexbytesstringmethod.py
1
import ast
1✔
2
from typing import Dict, Optional
1✔
3

4
from boa3.internal.model.builtin.classmethod.indexmethod import IndexMethod
1✔
5
from boa3.internal.model.expression import IExpression
1✔
6
from boa3.internal.model.type.primitive.bytestype import BytesType
1✔
7
from boa3.internal.model.type.primitive.strtype import StrType
1✔
8
from boa3.internal.model.variable import Variable
1✔
9
from boa3.internal.neo.vm.opcode.Opcode import Opcode
1✔
10

11

12
class IndexBytesStringMethod(IndexMethod):
1✔
13

14
    def __init__(self, self_type: Optional[StrType] = None):
1✔
15
        from boa3.internal.model.type.type import Type
1✔
16
        if not isinstance(self_type, (StrType, BytesType)):
1✔
17
            self_type = Type.str
1✔
18

19
        args: Dict[str, Variable] = {
1✔
20
            'self': Variable(self_type),
21
            'x': Variable(self_type),
22
            'start': Variable(Type.int),
23
            'end': Variable(Type.optional.build(Type.int)),
24
        }
25

26
        start_default = ast.parse("{0}".format(0)
1✔
27
                                  ).body[0].value
28
        end_default = ast.parse("{0}".format(Type.none.default_value)
1✔
29
                                ).body[0].value
30

31
        super().__init__(args, defaults=[start_default, end_default])
1✔
32

33
    def validate_parameters(self, *params: IExpression) -> bool:
1✔
34
        if 2 <= len(params) <= 4:
×
35
            return False
×
36
        if not all(isinstance(param, IExpression) for param in params):
×
37
            return False
×
38

39
        from boa3.internal.model.type.itype import IType
×
40
        self_type: IType = params[0].type
×
41

42
        if not isinstance(self_type, (StrType, BytesType)):
×
43
            return False
×
44

45
        if not self_type.is_type_of(params[1]):
×
46
            return False
×
47

48
        return True
×
49

50
    @property
1✔
51
    def error_message(self) -> str:
1✔
52
        return 'substring not found' if isinstance(self._arg_self.type, StrType) else 'subsequence of bytes not found'
1✔
53

54
    def generate_internal_opcodes(self, code_generator):
1✔
55
        from boa3.internal.model.builtin.builtin import Builtin
1✔
56
        from boa3.internal.model.operation.binaryop import BinaryOp
1✔
57

58
        # fix possible negative or too big indexes for start and end parameters
59
        code_generator.swap_reverse_stack_items(2)
1✔
60
        code_generator.swap_reverse_stack_items(4)
1✔
61
        code_generator.swap_reverse_stack_items(2)
1✔
62
        code_generator.fix_negative_index()
1✔
63
        code_generator.swap_reverse_stack_items(2)
1✔
64
        code_generator.duplicate_stack_top_item()
1✔
65
        code_generator.insert_type_check(None)
1✔
66
        if_end_is_none = code_generator.convert_begin_if()
1✔
67
        code_generator.change_jump(if_end_is_none, Opcode.JMPIFNOT)
1✔
68
        code_generator.remove_stack_top_item()
1✔
69
        code_generator.duplicate_stack_item(2)
1✔
70
        code_generator.convert_builtin_method_call(Builtin.Len, is_internal=True)
1✔
71
        else_end_is_not_none = code_generator.convert_begin_else(if_end_is_none, is_internal=True)
1✔
72
        code_generator.fix_negative_index()
1✔
73
        code_generator.convert_end_if(else_end_is_not_none, is_internal=True)
1✔
74
        code_generator.swap_reverse_stack_items(2)
1✔
75
        code_generator.fix_index_out_of_range(True)
1✔
76
        code_generator.swap_reverse_stack_items(2)
1✔
77
        code_generator.fix_index_out_of_range(True)
1✔
78
        code_generator.swap_reverse_stack_items(2)
1✔
79

80
        # change order of items on stack
81
        code_generator.duplicate_stack_item(4)
1✔
82
        code_generator.convert_builtin_method_call(Builtin.Len, is_internal=True)
1✔
83
        code_generator.swap_reverse_stack_items(3, rotate=True)
1✔
84
        code_generator.swap_reverse_stack_items(3, rotate=True)
1✔
85

86
        # current_index = start
87
        # while (size < end - current_index):
88
        while_start = code_generator.convert_begin_while()
1✔
89
        code_generator.duplicate_stack_item(4)
1✔
90
        code_generator.duplicate_stack_item(2)
1✔
91
        code_generator.duplicate_stack_item(5)
1✔
92
        code_generator.convert_get_substring(is_internal=True)
1✔
93
        code_generator.duplicate_stack_item(6)
1✔
94
        code_generator.convert_operation(BinaryOp.NumEq, is_internal=True)
1✔
95
        #   if str[index:current_index + size] == substr:
96
        if_was_found = code_generator.convert_begin_if()
1✔
97
        code_generator.change_jump(if_was_found, Opcode.JMPIFNOT)
1✔
98
        #       break
99
        code_generator.convert_loop_break()
1✔
100
        code_generator.convert_end_if(if_was_found)
1✔
101
        #   current_index += 1
102
        code_generator.insert_opcode(Opcode.INC)
1✔
103

104
        condition_address = code_generator.bytecode_size
1✔
105
        code_generator.duplicate_stack_item(2)
1✔
106
        code_generator.duplicate_stack_item(2)
1✔
107
        code_generator.convert_operation(BinaryOp.Sub, is_internal=True)
1✔
108
        code_generator.duplicate_stack_item(4)
1✔
109
        code_generator.convert_operation(BinaryOp.GtE, is_internal=True)
1✔
110
        code_generator.convert_end_while(while_start, condition_address, is_internal=True)
1✔
111

112
        # if current_index + size >= end:
113
        code_generator.duplicate_stack_item(2)
1✔
114
        code_generator.duplicate_stack_item(2)
1✔
115
        code_generator.convert_operation(BinaryOp.Sub, is_internal=True)
1✔
116
        code_generator.duplicate_stack_item(4)
1✔
117
        check_was_found = code_generator.convert_begin_if()
1✔
118
        code_generator.change_jump(check_was_found, Opcode.JMPGE)
1✔
119
        #   raise Exception('substring not found')
120
        code_generator.convert_literal(self.error_message)
1✔
121
        code_generator.convert_raise_exception()
1✔
122
        code_generator.convert_end_if(check_was_found)
1✔
123
        # else:
124
        #   return current_index
125
        for _ in range(1, len(code_generator._stack)):
1✔
126
            code_generator.remove_stack_item(2)
1✔
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc