Пример #1
0
def test_story_parse(patch, story):
    patch.init(Parser)
    patch.object(Parser, 'parse')
    story.parse()
    Parser.__init__.assert_called_with(ebnf_file=None)
    Parser.parse.assert_called_with(story.story, debug=False)
    assert story.tree == Parser.parse()
Пример #2
0
def test_ast(magic, patch):
    registry = magic()
    context = magic()
    patch.object(Parser, 'parse')
    patch.object(ASTAnalyzer, 'try_ast')
    context.line = 'foo'

    ast = ASTAnalyzer(service_registry=registry)
    result = ast.complete(context)

    Parser.parse.assert_called_with(context.line)
    ASTAnalyzer.try_ast.assert_called_with(Parser.parse(), context.word, False)

    assert result == ASTAnalyzer.try_ast()
Пример #3
0
def test_story_parse_lower(patch, story, parser):
    patch.object(Lowering, 'process')
    story.parse(parser=parser, lower=True)
    parser.parse.assert_called_with(story.story)
    Lowering.process.assert_called_with(Parser.parse())
    assert story.tree == Lowering.process(Lowering.process())
Пример #4
0
def test_story_parse(patch, story, parser):
    story.parse(parser=parser)
    parser.parse.assert_called_with(story.story)
    assert story.tree == Parser.parse()
Пример #5
0
def test_story_parse(patch, story, parser):
    story.parse(parser=parser)
    parser.parse.assert_called_with(story.story, allow_single_quotes=False)
    assert story.tree == Parser.parse()
Пример #6
0
class ASTAnalyzer:
    # TODO: add basic keywords
    # TODO: add existing variables
    # TODO: add existing functions

    def __init__(self, service_registry):
        self.parser = Parser()
        self.service_registry = service_registry

    def complete(self, context):
        is_space = len(context.line) > 0 and context.line[-1] == ' '
        log.debug(f"line: '{context.line}'")
        line = context.line
        if len(line.strip()) == 0:
            # start of a new line
            return self.complete_name()
        if ':' in line:
            return []
        try:
            if '=' in line:
                # try to convert assignments to expressions for now
                assignment = line.split('=')[-1]
                if len(assignment.strip()) > 0:
                    line = assignment
            ast = self.parser.parse(line, allow_single_quotes=False)
            log.debug(ast.pretty())
            return self.try_ast(ast, context.word, is_space)
        except UnexpectedCharacters as e:
            log.error(e)
            pass
        except UnexpectedToken as e:
            if 'NAME' in e.expected:
                return self.complete_name()
            log.error(e)
        return []

    def complete_name(self):
        # variables or services
        return self.get_services('')

    def try_ast(self, ast, word, is_space):
        if ast.block is not None:
            ast = ast.block
        if ast.rules is not None:
            ast = ast.rules
        if ast.service_block is not None:
            ast = ast.service_block.service
            if ast.service_fragment and \
                    ast.service_fragment.command is not None:
                service = ast.path.child(0).value
                if is_space:
                    # argument
                    command = ast.service_fragment.command.children[0].value
                    return self.get_arguments(service, command)

                # it's the command
                return self.get_commands(service)
            if is_space:
                # fresh command starts here
                service = ast.path.child(0).value
                return self.get_commands(service)
            else:
                return self.get_services(word)
        return []

    def get_arguments(self, service_name, command_name):
        service = self.service_registry.get_service(service_name)
        command = service.command(command_name)
        action = service.action(command_name)
        result = []
        if command is not None:
            result.extend(command.args())
        if action is not None:
            result.extend(action.args())
        return result

    def get_commands(self, service_name):
        service = self.service_registry.get_service(service_name)
        log.info(service.description())
        log.info(service.commands())
        return [
            *service.commands(),
            *service.actions(),
        ]

    def get_services(self, word):
        return self.service_registry.find_services(word)
Пример #7
0
def test_story_parse(patch, story, parser):
    story.parse()
    Parser.__init__.assert_called_with(ebnf=None)
    Parser.parse.assert_called_with(story.story)
    assert story.tree == Parser.parse()