• 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

97.83
/boa3/internal/model/builtin/classmethod/joinmethod.py
1
from typing import Any, Dict, Iterable, Optional, Union
1✔
2

3
from boa3.internal.model.builtin.method.builtinmethod import IBuiltinMethod
1✔
4
from boa3.internal.model.type.collection.mapping.mutable.dicttype import DictType
1✔
5
from boa3.internal.model.type.collection.sequence.sequencetype import SequenceType
1✔
6
from boa3.internal.model.type.primitive.ibytestringtype import IByteStringType
1✔
7
from boa3.internal.model.variable import Variable
1✔
8
from boa3.internal.neo.vm.opcode.Opcode import Opcode
1✔
9

10

11
class JoinMethod(IBuiltinMethod):
1✔
12
    def __init__(self, self_type: IByteStringType = None, iterable_type: Union[SequenceType, DictType] = None):
1✔
13
        from boa3.internal.model.type.type import Type
1✔
14

15
        if not isinstance(self_type, IByteStringType):
1✔
16
            self_type = Type.bytes
1✔
17

18
        if not isinstance(iterable_type, (SequenceType, DictType)):
1✔
19
            iterable_type = Type.sequence.build_collection([self_type])
1✔
20

21
        identifier = 'join'
1✔
22
        args: Dict[str, Variable] = {
1✔
23
            'self': Variable(self_type),
24
            'iterable': Variable(iterable_type),
25
        }
26

27
        super().__init__(identifier, args, return_type=self_type)
1✔
28

29
    @property
1✔
30
    def identifier(self) -> str:
1✔
31
        from boa3.internal.model.type.type import Type
1✔
32

33
        if Type.dict.is_type_of(self._arg_iterable.type):
1✔
34
            return '-{0}_{1}'.format(self._identifier, Type.dict.identifier)
1✔
35

36
        return self._identifier  # JoinMethod default value for self
1✔
37

38
    @property
1✔
39
    def _arg_self(self) -> Variable:
1✔
40
        return self.args['self']
1✔
41

42
    @property
1✔
43
    def _arg_iterable(self) -> Variable:
1✔
44
        return self.args['iterable']
1✔
45

46
    def push_self_first(self) -> bool:
1✔
47
        return self.has_self_argument
1✔
48

49
    def generate_internal_opcodes(self, code_generator):
1✔
50
        from boa3.internal.model.builtin.builtin import Builtin
1✔
51
        from boa3.internal.model.operation.binaryop import BinaryOp
1✔
52

53
        code_generator.duplicate_stack_top_item()
1✔
54
        # iterable_size = len(iterable)
55
        code_generator.convert_builtin_method_call(Builtin.Len, is_internal=True)
1✔
56
        # index = 0
57
        code_generator.convert_literal(0)
1✔
58
        code_generator.duplicate_stack_item(2)
1✔
59
        code_generator.duplicate_stack_item(2)
1✔
60

61
        # if iterable_size >= 0:
62
        if_iterable_not_empty = code_generator.convert_begin_if()
1✔
63
        code_generator.change_jump(if_iterable_not_empty, Opcode.JMPLE)
1✔
64

65
        from boa3.internal.model.type.type import Type
1✔
66
        if Type.dict.is_type_of(self._arg_iterable.type):
1✔
67
            code_generator.swap_reverse_stack_items(3)
1✔
68
            code_generator.convert_builtin_method_call(Builtin.DictKeys)
1✔
69
            code_generator.swap_reverse_stack_items(3)
1✔
70

71
        #   joined = iterable[0]
72
        code_generator.duplicate_stack_item(3)
1✔
73
        code_generator.duplicate_stack_item(2)
1✔
74
        code_generator.convert_get_item(index_inserted_internally=True)
1✔
75
        code_generator.swap_reverse_stack_items(2)
1✔
76
        #   index += 1
77
        code_generator.insert_opcode(Opcode.INC)
1✔
78
        code_generator.swap_reverse_stack_items(2)
1✔
79

80
        #   while index < iterable_size:
81
        while_start = code_generator.convert_begin_while()
1✔
82

83
        code_generator.duplicate_stack_item(5)
1✔
84
        #       joined = joined + string
85
        code_generator.convert_operation(BinaryOp.Concat, is_internal=True)
1✔
86
        code_generator.duplicate_stack_item(4)
1✔
87
        code_generator.duplicate_stack_item(3)
1✔
88
        code_generator.convert_get_item(index_inserted_internally=True)
1✔
89
        #       joined = joined + iterable[index]
90
        code_generator.convert_operation(BinaryOp.Concat, is_internal=True)
1✔
91
        code_generator.swap_reverse_stack_items(2)
1✔
92
        #       index += 1
93
        code_generator.insert_opcode(Opcode.INC)
1✔
94
        code_generator.swap_reverse_stack_items(2)
1✔
95

96
        # # while condition and end
97
        while_condition = code_generator.bytecode_size
1✔
98
        code_generator.duplicate_stack_item(2)
1✔
99
        code_generator.duplicate_stack_item(4)
1✔
100
        code_generator.convert_operation(BinaryOp.Lt)
1✔
101
        code_generator.convert_end_while(while_start, while_condition, is_internal=True)
1✔
102

103
        #   return joined
104
        code_generator.convert_cast(Type.str, is_internal=True)
1✔
105

106
        # elif iterable_size < 0:
107
        else_iterable_is_empty = code_generator.convert_begin_else(if_iterable_not_empty, is_internal=True)
1✔
108
        #   return ""
109
        code_generator.convert_literal("")
1✔
110
        code_generator.convert_end_if(else_iterable_is_empty)
1✔
111

112
        code_generator.remove_stack_item(2)
1✔
113
        code_generator.remove_stack_item(2)
1✔
114
        code_generator.remove_stack_item(2)
1✔
115
        code_generator.remove_stack_item(2)
1✔
116

117
    @property
1✔
118
    def _args_on_stack(self) -> int:
1✔
119
        return len(self.args)
1✔
120

121
    @property
1✔
122
    def _body(self) -> Optional[str]:
1✔
123
        return None
×
124

125
    def build(self, value: Any) -> IBuiltinMethod:
1✔
126
        if not isinstance(value, Iterable):
1✔
127
            value = [value]
1✔
128
        if isinstance(value, list) and len(value) <= 2:
1✔
129
            self_type = self._arg_self.type
1✔
130
            if len(value) < 2:
1✔
131
                value.append(None)
1✔
132
            if isinstance(value[0], type(self_type)) and isinstance(value[1], SequenceType):
1✔
133
                return self
1✔
134
            else:
135
                return JoinMethod(value[0], value[1])
1✔
136

137
        return super().build(value)
×
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