Exemple #1
0
    def process_as(self, stack, parse_state):
        """
        Process an upcoming 'as' rule and decide whether it can occur.
        """
        if parse_state.in_assignment:
            # use of 'as' in an assignment is definitely invalid
            return
        if parse_state.nestedness != 0:
            # use of 'as' inside parenthesis is definitely invalid
            return

        as_keyword = KeywordCompletionSymbol(
            "as", sort_group=SortGroup.ContextKeyword)
        suffixes = ["service_op", "service_suffix"]

        try:
            last_rule = Stack.find_closest_rule(stack, suffixes)
            service_name = Stack.extract(stack, "value",
                                         "service_suffix")[0].value
            service_command = Stack.extract(stack, last_rule)[0].value
        except Exception:
            # attempt to parse service_block failed - must be a when_block or
            # similar
            yield as_keyword
            return

        action = self.service_handler.action(service_name, service_command)
        if action is None:
            return

        # only yield 'as' iff the service can start an event block (=it has
        # events)
        if len(action.events()) > 0:
            yield as_keyword
Exemple #2
0
    def process_args(self, stack):
        """
        Looks for the mutation name token in the stack and filter seen arguments.
        """
        dot_op = self._toks(stack, before="mut_arguments")
        toks = [t.value for t in Stack.flatten(dot_op)]
        mut_name = toks.pop()
        # remove '.' from mut_name (.<mut_name>)
        expr = "".join(toks[:-1])

        # second or further arguments -> filter used arguments
        prev_args = Stack.find_all_until(stack,
                                         "mut_arguments", ["dot_expr"],
                                         start=1,
                                         offset=3)
        # '(' (<name> ':' <expr>)*
        prev_args = [*prev_args]

        args = self.args(expr, mut_name, prev_args)

        seen = {}
        for arg in args:
            arg_name = arg.name.lower()
            if arg_name in seen:
                continue
            seen[arg_name] = True
            # ignore previously used args
            if arg_name not in prev_args:
                yield arg
Exemple #3
0
 def _toks(self, stack, before=None):
     """
     Returns all tokens from the stack belonging to the current mutation.
     """
     return [
         *Stack.extract(stack, "dot_op", before),
         *Stack.extract(stack, "dot_expr", before),
     ]
Exemple #4
0
 def process_args(self, stack, prev_args):
     """
     Looks for the service name and command token in the
     Filters previously seen arguments.
     """
     service_name = Stack.extract(stack, "value", "service_suffix")[0].value
     service_command = Stack.extract(stack, "service_suffix")[0].value
     service = self._service_actions(service_name)
     args = Utils.action_args(service, service_command)
     yield from Utils.filter_prev_args(args, prev_args)
Exemple #5
0
    def _service_has_events(self, stack):
        """
        Returns `True` if the service has events.
        """
        service_name = Stack.extract(stack, "value")[0].value
        service_command = Stack.extract(stack, "service_op")[0].value

        action = self.service.action(service_name, service_command)
        if action is not None:
            if len(action.events()) > 0:
                return True

        return False
Exemple #6
0
    def process_when(self, stack):
        """
        Process a when statement without args.
        """
        name = Stack.extract(stack, "when_expression")[0].value
        when_action = Stack.extract(stack, "when_action")
        action = when_action[0].value
        prev_args = []
        try:
            event = Stack.extract(stack, "when_action_name")[0].value
        except Exception:
            # COLON (only two names provided, add the third name as argument)
            event = None
            prev_args.append(when_action[1].value)

        yield from self.service.when(name, action, event, prev_args)
Exemple #7
0
 def process_command(self, stack, value_stack_name, command_name):
     """
     Extract previous tokens for service argument completion.
     """
     actions = self.process_suffix(
         stack, value_stack_name, in_assignment=False
     )
     service_command = Stack.extract(stack, command_name)[0].value
     yield from Utils.action_args(actions, service_command)
Exemple #8
0
 def process_name(self, stack):
     """
     Extract previous token for mutation completion.
     """
     dot_op = self._toks(stack)
     toks = [t.value for t in Stack.flatten(dot_op)]
     # always remove the final dot
     assert toks[-1] == "."
     expr = "".join(toks[:-1])
     yield from self.dot.complete(expr)
Exemple #9
0
    def process_when_command(self, stack):
        """
        Extract previous tokens for service argument completion.
        """
        service_name = Stack.extract(stack, "when_expression")[0].value
        service_command = Stack.extract(stack, "when_action")[0].value
        _, ty = self.service_handler.check_service_var(service_name)
        if ty == ServiceVarType.Undefined:
            # variable was not declared -> must be a service with an action
            action = self.service_handler.action(service_name, service_command)
            if action is None:
                return
            for event in action.events():
                yield Event(event)
            return

        yield from self.when(
            service_name, service_command, event=None, prev_args=[]
        )
Exemple #10
0
 def process_args(self, stack, prev_args):
     """
     Looks for the function name token in the stack and filter seen arguments.
     """
     fn_name = Stack.extract(stack, "value", "fn_suffix")[0].value
     args = self.args(fn_name)
     for arg in args:
         arg_name = arg.name.lower()
         # ignore previously used args
         if arg_name not in prev_args:
             yield arg
Exemple #11
0
    def process_when_args(self, stack):
        """
        Process a when statement with args.
        """
        name = Stack.extract(stack, "when_expression")[0].value
        actions = Stack.extract(stack, "when_action")
        suffix = Stack.extract(stack, "when_action_suffix")
        prev_args = [
            *Stack.find_all_until(
                stack, "when_arglist", ["when_expression"], start=0, offset=3)
        ]
        event = None
        assert len(actions) == 2
        action = actions[0].value
        # it might have been the event name or an argument
        if len(suffix) > 0 and suffix[0].value == ":":
            prev_args.append(actions[1].value)
        else:
            event = actions[1].value

        yield from self.service.when(name, action, event, prev_args)
Exemple #12
0
    def process_args(self, stack):
        """
        Extract previous token for service or function argument completion
        with at least one previous argument. This looks for seen args
        and filters them out.
        """
        suffixes = ["fn_suffix", "service_suffix"]
        last_rule = Stack.find_closest_rule(stack, suffixes)

        # second or further arguments -> filter used arguments
        # <name> ':' <expr>
        prev_args = [
            *Stack.find_all_until(
                stack, "arglist", suffixes, start=0, offset=3)
        ]

        if last_rule == "service_suffix":
            yield from self.service.process_args(stack, prev_args)
        else:
            assert last_rule == "fn_suffix"
            yield from self.function.process_args(stack, prev_args)
Exemple #13
0
def test_extract():
    stack = Parser().stack("foo bar foo:1")
    res = Stack.extract(stack, "arglist", "value")
    assert len(res) == 2
    assert res[0].value == "foo"
    assert res[1].value == ":"
Exemple #14
0
def test_stack_find_all_until_no_rule():
    stack = Parser().stack("foo bar foo:1")
    with raises(AssertionError):
        [*Stack.find_all_until(stack, "arglist", ["no_rule"])]
Exemple #15
0
def test_stack_find_all_until_3():
    stack = Parser().stack("foo bar arg1:1 + 1 arg2:2 arg3: (foo bar arg4:1)")
    res = Stack.find_all_until(stack, "arglist", ["service_suffix"])
    assert [*res] == ["arg1", "arg2", "arg3"]
Exemple #16
0
def test_stack_find_all_until():
    stack = Parser().stack("foo bar arg1:1")
    res = Stack.find_all_until(stack, "arglist", ["service_suffix"])
    assert [*res] == ["arg1"]
Exemple #17
0
def test_stack_find_closest_rule():
    stack = Parser().stack("foo bar foo:1")
    res = Stack.find_closest_rule(stack, ["arglist", "no_rule"])
    assert res == "arglist"
Exemple #18
0
 def process_suffix(self, stack, value_stack_name, in_assignment):
     """
     Extract a service_suffix (=service_name) and yield its actions.
     """
     name = Stack.extract(stack, value_stack_name)[0].value
     yield from self._service_actions(name, in_assignment=in_assignment)
Exemple #19
0
 def process_name(self, stack):
     """
     Extract previous token for function completion.
     """
     fn_name = Stack.extract(stack, "value")[0].value
     yield from self.args(fn_name)
Exemple #20
0
def test_extract_seen_no_rule():
    stack = Parser().stack("foo bar foo:1")
    with raises(AssertionError):
        Stack.extract(stack, "arglist", "no_rule")
Exemple #21
0
def test_stack_find_closest_rule_no_rule():
    stack = Parser().stack("foo bar foo:1")
    with raises(AssertionError):
        Stack.find_closest_rule(stack, ["no_rule"])