Exemplo n.º 1
0
    def test_built_scope_tree_by_process_with_func_call(self):
        ast = self.create_ast(Fixtures.CALLING_FUNC)
        linker = ScopeLinker()

        linker.process(ast)

        expected_scope_tree = self.create_scope(
            ScopeVisibility.GLOBAL_LIKE,
            # no declarative variables
            variables={
                'g:': [self.create_variable()],
                'b:': [self.create_variable()],
                'w:': [self.create_variable()],
                't:': [self.create_variable()],
                'v:': [self.create_variable()],
            },
            child_scopes=[
                self.create_scope(
                    ScopeVisibility.SCRIPT_LOCAL,
                    variables={
                        's:': [self.create_variable()],
                    },
                )
            ]
        )

        self.assertScopeTreeEqual(expected_scope_tree, linker.scope_tree)
Exemplo n.º 2
0
    def test_built_scope_tree_by_process_with_declaring_var(self):
        ast = self.create_ast(Fixtures.DECLARING_VAR)
        linker = ScopeLinker()

        linker.process(ast)

        expected_scope_tree = self.create_scope(
            ScopeVisibility.GLOBAL_LIKE,
            variables={
                'g:': [self.create_variable()],
                'b:': [self.create_variable()],
                'w:': [self.create_variable()],
                't:': [self.create_variable()],
                'v:': [self.create_variable()],
                'g:explicit_global_var': [self.create_variable()],
                'b:buffer_local_var': [self.create_variable()],
                'w:window_local_var': [self.create_variable()],
                't:tab_local_var': [self.create_variable()],
                'g:implicit_global_var':
                [self.create_variable(is_implicit=True)],
                '$ENV_VAR': [self.create_variable()],
                '@"': [self.create_variable()],
                '&opt_var': [self.create_variable()],
                'v:count': [self.create_variable(is_builtin=True)],
            },
            child_scopes=[
                self.create_scope(ScopeVisibility.SCRIPT_LOCAL,
                                  variables={
                                      's:': [self.create_variable()],
                                      's:script_local_var':
                                      [self.create_variable()],
                                  })
            ])

        self.assertScopeTreeEqual(expected_scope_tree, linker.scope_tree)
Exemplo n.º 3
0
    def test_built_scope_tree_by_process_with_loop_var(self):
        ast = self.create_ast(Fixtures.LOOP_VAR)
        linker = ScopeLinker()

        linker.process(ast)

        expected_scope_tree = self.create_scope(
            ScopeVisibility.GLOBAL_LIKE,
            variables={
                'g:': [self.create_variable()],
                'b:': [self.create_variable()],
                'w:': [self.create_variable()],
                't:': [self.create_variable()],
                'v:': [self.create_variable()],
                'g:implicit_global_loop_var':
                [self.create_variable(is_implicit=True)]
            },
            child_scopes=[
                self.create_scope(ScopeVisibility.SCRIPT_LOCAL,
                                  variables={
                                      's:': [self.create_variable()],
                                  })
            ])

        self.assertScopeTreeEqual(expected_scope_tree, linker.scope_tree)
Exemplo n.º 4
0
    def test_built_scope_tree_by_process_with_destructuring_assignment(self):
        ast = self.create_ast(Fixtures.DESTRUCTURING_ASSIGNMENT)
        linker = ScopeLinker()

        linker.process(ast)

        expected_scope_tree = self.create_scope(
            ScopeVisibility.GLOBAL_LIKE,
            variables={
                'g:': [self.create_variable()],
                'b:': [self.create_variable()],
                'w:': [self.create_variable()],
                't:': [self.create_variable()],
                'v:': [self.create_variable()],
                'g:for_var1': [self.create_variable()],
                'g:for_var2': [self.create_variable()],
                'g:let_var1': [self.create_variable()],
                'g:let_var2': [self.create_variable()],
                'g:let_var3': [self.create_variable()],
                'g:rest': [self.create_variable()],
                # g:list members are not analyzable
            },
            child_scopes=[
                self.create_scope(
                    ScopeVisibility.SCRIPT_LOCAL,
                    variables={
                        's:': [self.create_variable()],
                    },
                )
            ]
        )

        self.assertScopeTreeEqual(expected_scope_tree, linker.scope_tree)
Exemplo n.º 5
0
    def test_built_scope_tree_by_process_with_loop_var(self):
        ast = self.create_ast(Fixtures.LOOP_VAR)
        linker = ScopeLinker()

        linker.process(ast)

        expected_scope_tree = self.create_scope(
            ScopeVisibility.GLOBAL_LIKE,
            variables={
                'g:': [self.create_variable()],
                'b:': [self.create_variable()],
                'w:': [self.create_variable()],
                't:': [self.create_variable()],
                'v:': [self.create_variable()],
                'g:implicit_global_loop_var': [self.create_variable(is_implicit=True)]
            },
            child_scopes=[
                self.create_scope(
                    ScopeVisibility.SCRIPT_LOCAL,
                    variables={
                        's:': [self.create_variable()],
                    }
                )
            ]
        )

        self.assertScopeTreeEqual(expected_scope_tree, linker.scope_tree)
Exemplo n.º 6
0
    def test_built_scope_tree_by_process_with_redir(self):
        ast = self.create_ast(Fixtures.REDIR)
        linker = ScopeLinker()

        linker.process(ast)

        expected_scope_tree = self.create_scope(
            ScopeVisibility.GLOBAL_LIKE,
            variables={
                'g:': [self.create_variable()],
                'b:': [self.create_variable()],
                'w:': [self.create_variable()],
                't:': [self.create_variable()],
                'v:': [self.create_variable()],
                'g:var': [self.create_variable()]
            },
            child_scopes=[
                self.create_scope(
                    ScopeVisibility.SCRIPT_LOCAL,
                    variables={
                        's:': [self.create_variable()],
                    }
                )
            ]
        )

        self.assertScopeTreeEqual(expected_scope_tree, linker.scope_tree)
Exemplo n.º 7
0
    def test_built_scope_tree_by_process_with_destructuring_assignment(self):
        ast = self.create_ast(Fixtures.DESTRUCTURING_ASSIGNMENT)
        linker = ScopeLinker()

        linker.process(ast)

        expected_scope_tree = self.create_scope(
            ScopeVisibility.GLOBAL_LIKE,
            variables={
                'g:': [self.create_variable()],
                'b:': [self.create_variable()],
                'w:': [self.create_variable()],
                't:': [self.create_variable()],
                'v:': [self.create_variable()],
                'g:for_var1': [self.create_variable()],
                'g:for_var2': [self.create_variable()],
                'g:let_var1': [self.create_variable()],
                'g:let_var2': [self.create_variable()],
                'g:let_var3': [self.create_variable()],
                'g:rest': [self.create_variable()],
                # g:list members are not analyzable
            },
            child_scopes=[
                self.create_scope(
                    ScopeVisibility.SCRIPT_LOCAL,
                    variables={
                        's:': [self.create_variable()],
                    },
                )
            ])

        self.assertScopeTreeEqual(expected_scope_tree, linker.scope_tree)
Exemplo n.º 8
0
    def test_built_scope_tree_by_process_with_func_call(self):
        ast = self.create_ast(Fixtures.CALLING_FUNC)
        linker = ScopeLinker()

        linker.process(ast)

        expected_scope_tree = self.create_scope(
            ScopeVisibility.GLOBAL_LIKE,
            # no declarative variables
            variables={
                'g:': [self.create_variable()],
                'b:': [self.create_variable()],
                'w:': [self.create_variable()],
                't:': [self.create_variable()],
                'v:': [self.create_variable()],
            },
            child_scopes=[
                self.create_scope(
                    ScopeVisibility.SCRIPT_LOCAL,
                    variables={
                        's:': [self.create_variable()],
                    },
                )
            ])

        self.assertScopeTreeEqual(expected_scope_tree, linker.scope_tree)
Exemplo n.º 9
0
    def test_built_scope_tree_by_process_with_lambda(self):
        ast = self.create_ast(Fixtures.LAMBDA)
        linker = ScopeLinker()

        linker.process(ast)

        expected_scope_tree = self.create_scope(
            ScopeVisibility.GLOBAL_LIKE,
            variables={
                'g:': [self.create_variable()],
                'b:': [self.create_variable()],
                'w:': [self.create_variable()],
                't:': [self.create_variable()],
                'v:': [self.create_variable()],
            },
            child_scopes=[
                self.create_scope(
                    ScopeVisibility.SCRIPT_LOCAL,
                    variables={
                        's:': [self.create_variable()],
                    },
                    child_scopes=[
                        self.create_scope(
                            ScopeVisibility.LAMBDA,
                            variables={
                                'i': [
                                    self.create_variable(
                                        explicity=ExplicityOfScopeVisibility.
                                        IMPLICIT_BUT_CONSTRAINED,
                                        is_explicit_lambda_argument=True,
                                    )
                                ],
                                'a:000': [self.create_variable()],
                                'a:0': [self.create_variable()],
                                'a:1': [self.create_variable()],
                                'a:2': [self.create_variable()],
                                'a:3': [self.create_variable()],
                                'a:4': [self.create_variable()],
                                'a:5': [self.create_variable()],
                                'a:6': [self.create_variable()],
                                'a:7': [self.create_variable()],
                                'a:8': [self.create_variable()],
                                'a:9': [self.create_variable()],
                                'a:10': [self.create_variable()],
                                'a:11': [self.create_variable()],
                                'a:12': [self.create_variable()],
                                'a:13': [self.create_variable()],
                                'a:14': [self.create_variable()],
                                'a:15': [self.create_variable()],
                                'a:16': [self.create_variable()],
                                'a:17': [self.create_variable()],
                                'a:18': [self.create_variable()],
                                'a:19': [self.create_variable()],
                            },
                        ),
                    ])
            ])

        self.assertScopeTreeEqual(expected_scope_tree, linker.scope_tree)
Exemplo n.º 10
0
    def test_built_scope_tree_by_process_with_declaring_func(self):
        ast = self.create_ast(Fixtures.DECLARING_FUNC)
        linker = ScopeLinker()

        linker.process(ast)

        expected_scope_tree = self.create_scope(
            ScopeVisibility.GLOBAL_LIKE,
            variables={
                'g:': [self.create_variable()],
                'b:': [self.create_variable()],
                'w:': [self.create_variable()],
                't:': [self.create_variable()],
                'v:': [self.create_variable()],
            },
            functions={
                'g:ExplicitGlobalFunc': [self.create_variable()],
                'g:ImplicitGlobalFunc':
                [self.create_variable(is_implicit=True)],
            },
            child_scopes=[
                self.create_scope(
                    ScopeVisibility.SCRIPT_LOCAL,
                    variables={
                        's:': [self.create_variable()],
                    },
                    functions={'s:ScriptLocalFunc': [self.create_variable()]},
                    child_scopes=[
                        self.create_scope(
                            ScopeVisibility.FUNCTION_LOCAL,
                            variables={
                                'l:': [self.create_variable()],
                                'a:': [self.create_variable()],
                                'a:0': [self.create_variable()],
                                'a:000': [self.create_variable()],
                            },
                        ),
                        self.create_scope(
                            ScopeVisibility.FUNCTION_LOCAL,
                            variables={
                                'l:': [self.create_variable()],
                                'a:': [self.create_variable()],
                                'a:0': [self.create_variable()],
                                'a:000': [self.create_variable()],
                            },
                        ),
                        self.create_scope(
                            ScopeVisibility.FUNCTION_LOCAL,
                            variables={
                                'l:': [self.create_variable()],
                                'a:': [self.create_variable()],
                                'a:0': [self.create_variable()],
                                'a:000': [self.create_variable()],
                            },
                        ),
                    ])
            ])

        self.assertScopeTreeEqual(expected_scope_tree, linker.scope_tree)
Exemplo n.º 11
0
    def test_built_scope_tree_by_process_with_lambda(self):
        ast = self.create_ast(Fixtures.LAMBDA)
        linker = ScopeLinker()

        linker.process(ast)

        expected_scope_tree = self.create_scope(
            ScopeVisibility.GLOBAL_LIKE,
            variables={
                'g:': [self.create_variable()],
                'b:': [self.create_variable()],
                'w:': [self.create_variable()],
                't:': [self.create_variable()],
                'v:': [self.create_variable()],
            },
            child_scopes=[
                self.create_scope(
                    ScopeVisibility.SCRIPT_LOCAL,
                    variables={
                        's:': [self.create_variable()],
                    },
                    child_scopes=[
                        self.create_scope(
                            ScopeVisibility.LAMBDA,
                            variables={
                                'i': [self.create_variable(
                                    explicity=ExplicityOfScopeVisibility.IMPLICIT_BUT_CONSTRAINED,
                                    is_explicit_lambda_argument=True,
                                )],
                                'a:000': [self.create_variable()],
                                'a:0': [self.create_variable()],
                                'a:1': [self.create_variable()],
                                'a:2': [self.create_variable()],
                                'a:3': [self.create_variable()],
                                'a:4': [self.create_variable()],
                                'a:5': [self.create_variable()],
                                'a:6': [self.create_variable()],
                                'a:7': [self.create_variable()],
                                'a:8': [self.create_variable()],
                                'a:9': [self.create_variable()],
                                'a:10': [self.create_variable()],
                                'a:11': [self.create_variable()],
                                'a:12': [self.create_variable()],
                                'a:13': [self.create_variable()],
                                'a:14': [self.create_variable()],
                                'a:15': [self.create_variable()],
                                'a:16': [self.create_variable()],
                                'a:17': [self.create_variable()],
                                'a:18': [self.create_variable()],
                                'a:19': [self.create_variable()],
                            },
                        ),
                    ]
                )
            ]
        )

        self.assertScopeTreeEqual(expected_scope_tree, linker.scope_tree)
Exemplo n.º 12
0
    def test_built_scope_tree_by_process_with_declaring_func_in_func(self):
        ast = self.create_ast(Fixtures.DECLARING_FUNC_IN_FUNC)
        linker = ScopeLinker()

        linker.process(ast)

        expected_scope_tree = self.create_scope(
            ScopeVisibility.GLOBAL_LIKE,
            variables={
                'g:': [self.create_variable()],
                'b:': [self.create_variable()],
                'w:': [self.create_variable()],
                't:': [self.create_variable()],
                'v:': [self.create_variable()],
            },
            functions={
                'FuncContext': [
                    self.create_variable(explicity=ExplicityOfScopeVisibility.
                                         IMPLICIT_BUT_CONSTRAINED)
                ],
                'ImplicitGlobalFunc': [
                    self.create_variable(explicity=ExplicityOfScopeVisibility.
                                         IMPLICIT_BUT_CONSTRAINED)
                ],
            },
            child_scopes=[
                self.create_scope(
                    ScopeVisibility.SCRIPT_LOCAL,
                    variables={
                        's:': [self.create_variable()],
                    },
                    child_scopes=[
                        self.create_scope(
                            ScopeVisibility.FUNCTION_LOCAL,
                            variables={
                                'l:': [self.create_variable()],
                                'a:': [self.create_variable()],
                                'a:0': [self.create_variable()],
                                'a:000': [self.create_variable()],
                            },
                            child_scopes=[
                                self.create_scope(
                                    ScopeVisibility.FUNCTION_LOCAL,
                                    variables={
                                        'l:': [self.create_variable()],
                                        'a:': [self.create_variable()],
                                        'a:0': [self.create_variable()],
                                        'a:000': [self.create_variable()],
                                    }),
                            ]),
                    ])
            ])

        self.assertScopeTreeEqual(expected_scope_tree, linker.scope_tree)
Exemplo n.º 13
0
    def test_built_scope_tree_by_process_with_declaring_func_in_func(self):
        ast = self.create_ast(Fixtures.DECLARING_FUNC_IN_FUNC)
        linker = ScopeLinker()

        linker.process(ast)

        expected_scope_tree = self.create_scope(
            ScopeVisibility.GLOBAL_LIKE,
            variables={
                'g:': [self.create_variable()],
                'b:': [self.create_variable()],
                'w:': [self.create_variable()],
                't:': [self.create_variable()],
                'v:': [self.create_variable()],
            },
            functions={
                'g:FuncContext': [self.create_variable(is_implicit=True)],
                'g:ImplicitGlobalFunc': [self.create_variable(is_implicit=True)],
            },
            child_scopes=[
                self.create_scope(
                    ScopeVisibility.SCRIPT_LOCAL,
                    variables={
                        's:': [self.create_variable()],
                    },
                    child_scopes=[
                        self.create_scope(
                            ScopeVisibility.FUNCTION_LOCAL,
                            variables={
                                'l:': [self.create_variable()],
                                'a:': [self.create_variable()],
                                'a:0': [self.create_variable()],
                                'a:000': [self.create_variable()],
                            },
                            child_scopes=[
                                self.create_scope(
                                    ScopeVisibility.FUNCTION_LOCAL,
                                    variables={
                                        'l:': [self.create_variable()],
                                        'a:': [self.create_variable()],
                                        'a:0': [self.create_variable()],
                                        'a:000': [self.create_variable()],
                                    }
                                ),
                            ]
                        ),
                    ]
                )
            ]
        )

        self.assertScopeTreeEqual(expected_scope_tree, linker.scope_tree)
Exemplo n.º 14
0
    def test_built_scope_tree_by_process_with_declaring_with_dict_key(self):
        ast = self.create_ast(Fixtures.DICT_KEY)
        linker = ScopeLinker()

        linker.process(ast)

        expected_scope_tree = self.create_scope(
            ScopeVisibility.GLOBAL_LIKE,
            variables={
                'g:': [self.create_variable()],
                'b:': [self.create_variable()],
                'w:': [self.create_variable()],
                't:': [self.create_variable()],
                'v:': [self.create_variable()],
                # Member functions are not analyzable
            },
            child_scopes=[
                self.create_scope(
                    ScopeVisibility.SCRIPT_LOCAL,
                    variables={
                        's:': [self.create_variable()],
                        # Member functions are not analyzable
                    },
                    child_scopes=[
                        self.create_scope(
                            ScopeVisibility.FUNCTION_LOCAL,
                            variables={
                                'l:': [self.create_variable()],
                                'l:self': [self.create_variable()],
                                'a:': [self.create_variable()],
                                'a:0': [self.create_variable()],
                                'a:000': [self.create_variable()],
                            }
                        ),
                        self.create_scope(
                            ScopeVisibility.FUNCTION_LOCAL,
                            variables={
                                'l:': [self.create_variable()],
                                'l:self': [self.create_variable()],
                                'a:': [self.create_variable()],
                                'a:0': [self.create_variable()],
                                'a:000': [self.create_variable()],
                            }
                        ),
                    ]
                )
            ]
        )

        self.assertScopeTreeEqual(expected_scope_tree, linker.scope_tree)
Exemplo n.º 15
0
    def test_built_scope_tree_by_process_with_declaring_with_dict_key(self):
        ast = self.create_ast(Fixtures.DICT_KEY)
        linker = ScopeLinker()

        linker.process(ast)

        expected_scope_tree = self.create_scope(
            ScopeVisibility.GLOBAL_LIKE,
            variables={
                'g:': [self.create_variable()],
                'b:': [self.create_variable()],
                'w:': [self.create_variable()],
                't:': [self.create_variable()],
                'v:': [self.create_variable()],
                # Member functions are not analyzable
            },
            child_scopes=[
                self.create_scope(
                    ScopeVisibility.SCRIPT_LOCAL,
                    variables={
                        's:': [self.create_variable()],
                        # Member functions are not analyzable
                    },
                    child_scopes=[
                        self.create_scope(ScopeVisibility.FUNCTION_LOCAL,
                                          variables={
                                              'l:': [self.create_variable()],
                                              'l:self':
                                              [self.create_variable()],
                                              'a:': [self.create_variable()],
                                              'a:0': [self.create_variable()],
                                              'a:000':
                                              [self.create_variable()],
                                          }),
                        self.create_scope(ScopeVisibility.FUNCTION_LOCAL,
                                          variables={
                                              'l:': [self.create_variable()],
                                              'l:self':
                                              [self.create_variable()],
                                              'a:': [self.create_variable()],
                                              'a:0': [self.create_variable()],
                                              'a:000':
                                              [self.create_variable()],
                                          }),
                    ])
            ])

        self.assertScopeTreeEqual(expected_scope_tree, linker.scope_tree)
Exemplo n.º 16
0
    def test_built_declarative_identifier_links_by_process(self):
        ast = self.create_ast(Fixtures.DECLARING_AND_REFERENCING)

        # Function name identifier node
        dec_id_node = ast['body'][0]['left']

        linker = ScopeLinker()
        linker.process(ast)

        scope_tree = linker.scope_tree
        # Expect a script local scope
        expected_scope = scope_tree['child_scopes'][0]

        link_registry = linker.link_registry
        actual_scope = link_registry.get_context_scope_by_identifier(dec_id_node)

        self.assertScopeTreeEqual(expected_scope, actual_scope)
Exemplo n.º 17
0
    def test_built_reference_variable_links_by_process(self):
        ast = self.create_ast(Fixtures.DECLARING_AND_REFERENCING)

        # Function name identifier node
        expected_dec_id = ast['body'][0]['left']

        linker = ScopeLinker()
        linker.process(ast)

        scope_tree = linker.scope_tree
        # Function local scope
        scope = scope_tree['child_scopes'][0]
        variable_func = scope['functions']['s:Function'][0]

        link_registry = linker.link_registry
        actual_dec_id = link_registry.get_declarative_identifier_by_variable(variable_func)

        self.assertScopeTreeEqual(expected_dec_id, actual_dec_id)
Exemplo n.º 18
0
    def test_built_declarative_identifier_links_by_process(self):
        ast = self.create_ast(Fixtures.DECLARING_AND_REFERENCING)

        # Function name identifier node
        dec_id_node = ast['body'][0]['left']

        linker = ScopeLinker()
        linker.process(ast)

        scope_tree = linker.scope_tree
        # Expect a script local scope
        expected_scope = scope_tree['child_scopes'][0]

        link_registry = linker.link_registry
        actual_scope = link_registry.get_context_scope_by_identifier(
            dec_id_node)

        self.assertScopeTreeEqual(expected_scope, actual_scope)
Exemplo n.º 19
0
    def test_built_reference_variable_links_by_process(self):
        ast = self.create_ast(Fixtures.DECLARING_AND_REFERENCING)

        # Function name identifier node
        expected_dec_id = ast['body'][0]['left']

        linker = ScopeLinker()
        linker.process(ast)

        scope_tree = linker.scope_tree
        # Function local scope
        scope = scope_tree['child_scopes'][0]
        variable_func = scope['functions']['s:Function'][0]

        link_registry = linker.link_registry
        actual_dec_id = link_registry.get_declarative_identifier_by_variable(
            variable_func)

        self.assertScopeTreeEqual(expected_dec_id, actual_dec_id)
Exemplo n.º 20
0
    def test_built_scope_tree_by_process_with_declaring_var_in_func(self):
        ast = self.create_ast(Fixtures.DECLARING_VAR_IN_FUNC)
        linker = ScopeLinker()

        linker.process(ast)

        expected_scope_tree = self.create_scope(
            ScopeVisibility.GLOBAL_LIKE,
            variables={
                'g:': [self.create_variable()],
                'b:': [self.create_variable()],
                'w:': [self.create_variable()],
                't:': [self.create_variable()],
                'v:': [self.create_variable()],
            },
            functions={
                'FuncContext': [self.create_variable(explicity=ExplicityOfScopeVisibility.IMPLICIT_BUT_CONSTRAINED)],
            },
            child_scopes=[
                self.create_scope(
                    ScopeVisibility.SCRIPT_LOCAL,
                    variables={
                        's:': [self.create_variable()],
                    },
                    child_scopes=[
                        self.create_scope(
                            ScopeVisibility.FUNCTION_LOCAL,
                            variables={
                                'l:': [self.create_variable()],
                                'a:': [self.create_variable()],
                                'a:0': [self.create_variable()],
                                'a:000': [self.create_variable()],
                                'explicit_func_local_var': [self.create_variable()],
                                'implicit_func_local_var': [self.create_variable(explicity=ExplicityOfScopeVisibility.IMPLICIT)],
                            }
                        )
                    ]
                )
            ]
        )

        self.assertScopeTreeEqual(expected_scope_tree, linker.scope_tree)
Exemplo n.º 21
0
    def test_built_scope_tree_by_process_with_declaring_var_in_func(self):
        ast = self.create_ast(Fixtures.DECLARING_VAR_IN_FUNC)
        linker = ScopeLinker()

        linker.process(ast)

        expected_scope_tree = self.create_scope(
            ScopeVisibility.GLOBAL_LIKE,
            variables={
                'g:': [self.create_variable()],
                'b:': [self.create_variable()],
                'w:': [self.create_variable()],
                't:': [self.create_variable()],
                'v:': [self.create_variable()],
            },
            functions={
                'g:FuncContext': [self.create_variable(is_implicit=True)],
            },
            child_scopes=[
                self.create_scope(
                    ScopeVisibility.SCRIPT_LOCAL,
                    variables={
                        's:': [self.create_variable()],
                    },
                    child_scopes=[
                        self.create_scope(
                            ScopeVisibility.FUNCTION_LOCAL,
                            variables={
                                'l:': [self.create_variable()],
                                'a:': [self.create_variable()],
                                'a:0': [self.create_variable()],
                                'a:000': [self.create_variable()],
                                'l:explicit_func_local_var':
                                [self.create_variable()],
                                'l:implicit_func_local_var':
                                [self.create_variable(is_implicit=True)],
                            })
                    ])
            ])

        self.assertScopeTreeEqual(expected_scope_tree, linker.scope_tree)
    def process(self, ast):
        scope_linker = ScopeLinker()
        scope_linker.process(ast)

        id_collector = IdentifierClassifier.IdentifierCollector()
        classified_id_group = id_collector.collect_identifiers(ast)
        dec_id_nodes = classified_id_group['static_declaring_identifiers']
        ref_id_nodes = classified_id_group['static_referencing_identifiers']

        self._scope_tree = scope_linker.scope_tree
        self._link_registry = scope_linker.link_registry

        # Attach a parent_scope accessor to the scope tree
        ReferenceReachabilityTester.TwoWayScopeReferenceAttacher.attach(
            self._scope_tree)

        # Reset REFERECED_FLAG to False
        for dec_id_node in dec_id_nodes:
            dec_id_node[REFERECED_FLAG] = False

        for ref_id_node in ref_id_nodes:
            is_reachable = self.check_reachability(ref_id_node)
            ref_id_node[REACHABILITY_FLAG] = is_reachable
Exemplo n.º 23
0
    def test_built_scope_tree_by_process_with_declaring_var(self):
        ast = self.create_ast(Fixtures.DECLARING_VAR)
        linker = ScopeLinker()

        linker.process(ast)

        expected_scope_tree = self.create_scope(
            ScopeVisibility.GLOBAL_LIKE,
            variables={
                'g:': [self.create_variable()],
                'b:': [self.create_variable()],
                'w:': [self.create_variable()],
                't:': [self.create_variable()],
                'v:': [self.create_variable()],
                'g:explicit_global_var': [self.create_variable()],
                'b:buffer_local_var': [self.create_variable()],
                'w:window_local_var': [self.create_variable()],
                't:tab_local_var': [self.create_variable()],
                'g:implicit_global_var': [self.create_variable(is_implicit=True)],
                '$ENV_VAR': [self.create_variable()],
                '@"': [self.create_variable()],
                '&opt_var': [self.create_variable()],
                'v:count': [self.create_variable(is_builtin=True)],
            },
            child_scopes=[
                self.create_scope(
                    ScopeVisibility.SCRIPT_LOCAL,
                    variables={
                        's:': [self.create_variable()],
                        's:script_local_var': [self.create_variable()],
                    }
                )
            ]
        )

        self.assertScopeTreeEqual(expected_scope_tree, linker.scope_tree)
Exemplo n.º 24
0
    def test_built_scope_tree_by_process_with_redir(self):
        ast = self.create_ast(Fixtures.REDIR)
        linker = ScopeLinker()

        linker.process(ast)

        expected_scope_tree = self.create_scope(
            ScopeVisibility.GLOBAL_LIKE,
            variables={
                'g:': [self.create_variable()],
                'b:': [self.create_variable()],
                'w:': [self.create_variable()],
                't:': [self.create_variable()],
                'v:': [self.create_variable()],
                'g:var': [self.create_variable()]
            },
            child_scopes=[
                self.create_scope(ScopeVisibility.SCRIPT_LOCAL,
                                  variables={
                                      's:': [self.create_variable()],
                                  })
            ])

        self.assertScopeTreeEqual(expected_scope_tree, linker.scope_tree)
Exemplo n.º 25
0
    def test_built_scope_tree_by_process_with_declaring_func(self):
        ast = self.create_ast(Fixtures.DECLARING_FUNC)
        linker = ScopeLinker()

        linker.process(ast)

        expected_scope_tree = self.create_scope(
            ScopeVisibility.GLOBAL_LIKE,
            variables={
                'g:': [self.create_variable()],
                'b:': [self.create_variable()],
                'w:': [self.create_variable()],
                't:': [self.create_variable()],
                'v:': [self.create_variable()],
            },
            functions={
                'ExplicitGlobalFunc': [self.create_variable(explicity=ExplicityOfScopeVisibility.UNRECOMMENDED_EXPLICIT)],
                'ImplicitGlobalFunc': [self.create_variable(explicity=ExplicityOfScopeVisibility.IMPLICIT_BUT_CONSTRAINED)],
            },
            child_scopes=[
                self.create_scope(
                    ScopeVisibility.SCRIPT_LOCAL,
                    variables={
                        's:': [self.create_variable()],
                    },
                    functions={
                        's:ScriptLocalFunc': [self.create_variable()]
                    },
                    child_scopes=[
                        self.create_scope(
                            ScopeVisibility.FUNCTION_LOCAL,
                            variables={
                                'l:': [self.create_variable()],
                                'a:': [self.create_variable()],
                                'a:0': [self.create_variable()],
                                'a:000': [self.create_variable()],
                            },
                        ),
                        self.create_scope(
                            ScopeVisibility.FUNCTION_LOCAL,
                            variables={
                                'l:': [self.create_variable()],
                                'a:': [self.create_variable()],
                                'a:0': [self.create_variable()],
                                'a:000': [self.create_variable()],
                            },
                        ),
                        self.create_scope(
                            ScopeVisibility.FUNCTION_LOCAL,
                            variables={
                                'l:': [self.create_variable()],
                                'a:': [self.create_variable()],
                                'a:0': [self.create_variable()],
                                'a:000': [self.create_variable()],
                            },
                        ),
                    ]
                )
            ]
        )

        self.assertScopeTreeEqual(expected_scope_tree, linker.scope_tree)
Exemplo n.º 26
0
    def test_built_scope_tree_by_process_with_func_param(self):
        ast = self.create_ast(Fixtures.FUNC_PARAM)
        linker = ScopeLinker()

        linker.process(ast)

        expected_scope_tree = self.create_scope(
            ScopeVisibility.GLOBAL_LIKE,
            variables={
                'g:': [self.create_variable()],
                'b:': [self.create_variable()],
                'w:': [self.create_variable()],
                't:': [self.create_variable()],
                'v:': [self.create_variable()],
            },
            functions={
                'g:FunctionWithNoParams': [self.create_variable()],
                'g:FunctionWithOneParam': [self.create_variable()],
                'g:FunctionWithTwoParams': [self.create_variable()],
                'g:FunctionWithVarParams': [self.create_variable()],
                'g:FunctionWithParamsAndVarParams': [self.create_variable()],
                'g:FunctionWithRange': [self.create_variable()],
                'g:FunctionWithDict': [self.create_variable()],
            },
            child_scopes=[
                self.create_scope(
                    ScopeVisibility.SCRIPT_LOCAL,
                    variables={
                        's:': [self.create_variable()],
                    },
                    child_scopes=[
                        self.create_scope(
                            ScopeVisibility.FUNCTION_LOCAL,
                            variables={
                                'l:': [self.create_variable()],
                                'a:': [self.create_variable()],
                                'a:0': [self.create_variable()],
                                'a:000': [self.create_variable()],
                            }
                        ),
                        self.create_scope(
                            ScopeVisibility.FUNCTION_LOCAL,
                            variables={
                                'l:': [self.create_variable()],
                                'a:': [self.create_variable()],
                                'a:0': [self.create_variable()],
                                'a:000': [self.create_variable()],
                                'a:param': [self.create_variable()],
                            }
                        ),
                        self.create_scope(
                            ScopeVisibility.FUNCTION_LOCAL,
                            variables={
                                'l:': [self.create_variable()],
                                'a:': [self.create_variable()],
                                'a:0': [self.create_variable()],
                                'a:000': [self.create_variable()],
                                'a:param1': [self.create_variable()],
                                'a:param2': [self.create_variable()],
                            }
                        ),
                        self.create_scope(
                            ScopeVisibility.FUNCTION_LOCAL,
                            variables={
                                'l:': [self.create_variable()],
                                'a:': [self.create_variable()],
                                'a:0': [self.create_variable()],
                                'a:1': [self.create_variable()],
                                'a:2': [self.create_variable()],
                                'a:3': [self.create_variable()],
                                'a:4': [self.create_variable()],
                                'a:5': [self.create_variable()],
                                'a:6': [self.create_variable()],
                                'a:7': [self.create_variable()],
                                'a:8': [self.create_variable()],
                                'a:9': [self.create_variable()],
                                'a:10': [self.create_variable()],
                                'a:11': [self.create_variable()],
                                'a:12': [self.create_variable()],
                                'a:13': [self.create_variable()],
                                'a:14': [self.create_variable()],
                                'a:15': [self.create_variable()],
                                'a:16': [self.create_variable()],
                                'a:17': [self.create_variable()],
                                'a:18': [self.create_variable()],
                                'a:19': [self.create_variable()],
                                'a:20': [self.create_variable()],
                                'a:000': [self.create_variable()],
                            }
                        ),
                        self.create_scope(
                            ScopeVisibility.FUNCTION_LOCAL,
                            variables={
                                'l:': [self.create_variable()],
                                'a:': [self.create_variable()],
                                'a:param_var1': [self.create_variable()],
                                'a:0': [self.create_variable()],
                                'a:1': [self.create_variable()],
                                'a:2': [self.create_variable()],
                                'a:3': [self.create_variable()],
                                'a:4': [self.create_variable()],
                                'a:5': [self.create_variable()],
                                'a:6': [self.create_variable()],
                                'a:7': [self.create_variable()],
                                'a:8': [self.create_variable()],
                                'a:9': [self.create_variable()],
                                'a:10': [self.create_variable()],
                                'a:11': [self.create_variable()],
                                'a:12': [self.create_variable()],
                                'a:13': [self.create_variable()],
                                'a:14': [self.create_variable()],
                                'a:15': [self.create_variable()],
                                'a:16': [self.create_variable()],
                                'a:17': [self.create_variable()],
                                'a:18': [self.create_variable()],
                                'a:19': [self.create_variable()],
                                'a:000': [self.create_variable()],
                            }
                        ),
                        self.create_scope(
                            ScopeVisibility.FUNCTION_LOCAL,
                            variables={
                                'l:': [self.create_variable()],
                                'a:': [self.create_variable()],
                                'a:param': [self.create_variable()],
                                'a:0': [self.create_variable()],
                                'a:000': [self.create_variable()],
                                'a:firstline': [self.create_variable()],
                                'a:lastline': [self.create_variable()],
                            }
                        ),
                        self.create_scope(
                            ScopeVisibility.FUNCTION_LOCAL,
                            variables={
                                'l:': [self.create_variable()],
                                'l:self': [self.create_variable()],
                                'a:': [self.create_variable()],
                                'a:0': [self.create_variable()],
                                'a:000': [self.create_variable()],
                            }
                        ),
                    ]
                )
            ]
        )

        self.assertScopeTreeEqual(expected_scope_tree, linker.scope_tree)
class ReferenceReachabilityTester(object):
    """ A class for tester for reference reachability. """
    class TwoWayScopeReferenceAttacher(object):
        """ A class for AST processor to do attach to way reference between
        a parent scope and the child scopes.
        """
        @classmethod
        def attach(cls, root_scope_tree):
            # type: (Scope) -> Scope
            root_scope_tree.parent = None

            return cls._attach_recursively(root_scope_tree)

        @classmethod
        def _attach_recursively(cls, scope_tree):
            # type: (Scope) -> Scope
            for child_scope in scope_tree.child_scopes:
                child_scope.parent = scope_tree
                cls._attach_recursively(child_scope)

            return scope_tree

    def __init__(self):
        self._scope_linker = ScopeLinker()  # type: ScopeLinker

    def process(self, ast):
        self._scope_linker.process(ast)

        id_collector = IdentifierClassifier.IdentifierCollector()
        classified_id_group = id_collector.collect_identifiers(ast)
        dec_id_nodes = classified_id_group.statically_declared_identifiers
        ref_id_nodes = classified_id_group.statically_referencing_identifiers

        # Attach a parent_scope accessor to the scope tree
        ReferenceReachabilityTester.TwoWayScopeReferenceAttacher.attach(
            self._scope_linker.scope_tree)

        # Reset REFERENCED_FLAG to False
        for dec_id_node in dec_id_nodes:
            dec_id_node[REFERENCED_FLAG] = False

        for ref_id_node in ref_id_nodes:
            is_reachable = self.check_reachability(ref_id_node)
            ref_id_node[REACHABILITY_FLAG] = is_reachable

    def get_objective_scope_visibility(
            self, decl_or_ref_id_node
    ):  # type: (Dict[str, Any]) -> ScopeVisibilityHint
        """ Returns a objective scope visibility by a declarative identifier node or a reference identifier node. """
        context_scope = self._scope_linker.link_registry.get_context_scope_by_identifier(
            decl_or_ref_id_node)
        possible_visibility_hint = detect_possible_scope_visibility(
            decl_or_ref_id_node, context_scope)
        possible_explicity = possible_visibility_hint.explicity

        # Return the visibility soon if the node already have a determined visibility.
        if possible_explicity is not ExplicityOfScopeVisibility.IMPLICIT_OR_LAMBDA:
            determined_visibility_hint = possible_visibility_hint
            return determined_visibility_hint

        # The node have IMPLICIT_OR_LAMBDA can be only reference identifier nodes.
        # SEE: detect_possible_scope_visibility
        ref_id_node = decl_or_ref_id_node

        # It is constrained implicit if it is a lambda argument.
        if self._is_reference_to_lambda_argument(ref_id_node):
            return ScopeVisibilityHint(
                scope_visibility=possible_visibility_hint.scope_visibility,
                explicity=ExplicityOfScopeVisibility.IMPLICIT_BUT_CONSTRAINED,
            )

        # Otherwise it is implicit.
        return ScopeVisibilityHint(
            scope_visibility=possible_visibility_hint.scope_visibility,
            explicity=ExplicityOfScopeVisibility.IMPLICIT)

    def _reset_referenced_flag(self, scope_tree):  # type: (Scope) -> None
        for child_scope in scope_tree.child_scopes:
            for functions in child_scope.functions.values():
                for func in functions:
                    decl_id_node = self._scope_linker.link_registry.get_declarative_identifier_by_variable(
                        func)
                    decl_id_node[REFERENCED_FLAG] = False

            for variables in child_scope.variables.values():
                for variable in variables:
                    decl_id_node = self._scope_linker.link_registry.get_declarative_identifier_by_variable(
                        variable)
                    decl_id_node[REFERENCED_FLAG] = False

            self._reset_referenced_flag(child_scope)

    def get_referenced_variable_declarations(self, ref_id_node):
        # type: (Dict[str, Any]) -> Union[List[VariableDeclaration], GlobalVariableDeclaration]

        scope = self._scope_linker.link_registry.get_context_scope_by_identifier(
            ref_id_node)
        var_name = remove_optional_scope_prefix(ref_id_node['value'])
        is_func_id = is_function_identifier(ref_id_node)

        while scope is not None:
            if is_func_id:
                functions_list = scope.functions
                if var_name in functions_list:
                    # The function is found in the symbol table for functions.
                    funcs = functions_list[var_name]

                    for func in funcs:
                        declaring_id_node = self._scope_linker.link_registry \
                            .get_declarative_identifier_by_variable(func)
                        declaring_id_node[REFERENCED_FLAG] = True

                    return funcs
                else:
                    # We can access the function via a variable function
                    # reference if the function not found from the symbol table
                    # for functions. So we should check the symbol table for
                    # variables to search the function reference.
                    pass

            variables_list = scope.variables
            if var_name in variables_list:
                # The variable or function reference found in the symbol table
                # for variables.
                variables = variables_list[var_name]

                for variable in variables:
                    declaring_id_node = self._scope_linker.link_registry \
                        .get_declarative_identifier_by_variable(variable)
                    declaring_id_node[REFERENCED_FLAG] = True

                return variables

            scope = scope.parent

        # If it is builtin, it will be used by Vim.
        if is_builtin_variable(ref_id_node):
            return GLOBAL_VARIABLE_DECLARATION

        return []

    def check_reachability(self,
                           ref_id_node):  # type: (Dict[str, Any]) -> bool
        # NOTE: We can only assume dynamic identifiers can reach.
        if is_dynamic_identifier(ref_id_node):
            return True

        declarative_variables_or_global = self.get_referenced_variable_declarations(
            ref_id_node)

        if isinstance(declarative_variables_or_global,
                      GlobalVariableDeclaration):
            # NOTE: It is a global like variable, so we can only assume it can reach.
            return True

        # NOTE: It is reachable if at least one declarative identifier can reach to found.
        return len(declarative_variables_or_global) > 0

    def _is_reference_to_lambda_argument(
            self, ref_id_node):  # type: (Dict[str, Any]) -> bool
        # NOTE: We can only assume dynamic identifiers can reach.
        if is_dynamic_identifier(ref_id_node):
            return True

        declarative_variables_or_global = self.get_referenced_variable_declarations(
            ref_id_node)

        if isinstance(declarative_variables_or_global,
                      GlobalVariableDeclaration):
            return False

        declarative_variables = declarative_variables_or_global

        for declarative_variable in declarative_variables:
            if declarative_variable.is_explicit_lambda_argument:
                return True

        return False
Exemplo n.º 28
0
    def test_built_scope_tree_by_process_with_func_param(self):
        ast = self.create_ast(Fixtures.FUNC_PARAM)
        linker = ScopeLinker()

        linker.process(ast)

        expected_scope_tree = self.create_scope(
            ScopeVisibility.GLOBAL_LIKE,
            variables={
                'g:': [self.create_variable()],
                'b:': [self.create_variable()],
                'w:': [self.create_variable()],
                't:': [self.create_variable()],
                'v:': [self.create_variable()],
            },
            functions={
                'g:FunctionWithNoParams': [self.create_variable()],
                'g:FunctionWithOneParam': [self.create_variable()],
                'g:FunctionWithTwoParams': [self.create_variable()],
                'g:FunctionWithVarParams': [self.create_variable()],
                'g:FunctionWithParamsAndVarParams': [self.create_variable()],
                'g:FunctionWithRange': [self.create_variable()],
                'g:FunctionWithDict': [self.create_variable()],
            },
            child_scopes=[
                self.create_scope(
                    ScopeVisibility.SCRIPT_LOCAL,
                    variables={
                        's:': [self.create_variable()],
                    },
                    child_scopes=[
                        self.create_scope(ScopeVisibility.FUNCTION_LOCAL,
                                          variables={
                                              'l:': [self.create_variable()],
                                              'a:': [self.create_variable()],
                                              'a:0': [self.create_variable()],
                                              'a:000':
                                              [self.create_variable()],
                                          }),
                        self.create_scope(ScopeVisibility.FUNCTION_LOCAL,
                                          variables={
                                              'l:': [self.create_variable()],
                                              'a:': [self.create_variable()],
                                              'a:0': [self.create_variable()],
                                              'a:000':
                                              [self.create_variable()],
                                              'a:param':
                                              [self.create_variable()],
                                          }),
                        self.create_scope(ScopeVisibility.FUNCTION_LOCAL,
                                          variables={
                                              'l:': [self.create_variable()],
                                              'a:': [self.create_variable()],
                                              'a:0': [self.create_variable()],
                                              'a:000':
                                              [self.create_variable()],
                                              'a:param1':
                                              [self.create_variable()],
                                              'a:param2':
                                              [self.create_variable()],
                                          }),
                        self.create_scope(ScopeVisibility.FUNCTION_LOCAL,
                                          variables={
                                              'l:': [self.create_variable()],
                                              'a:': [self.create_variable()],
                                              'a:0': [self.create_variable()],
                                              'a:1': [self.create_variable()],
                                              'a:2': [self.create_variable()],
                                              'a:3': [self.create_variable()],
                                              'a:4': [self.create_variable()],
                                              'a:5': [self.create_variable()],
                                              'a:6': [self.create_variable()],
                                              'a:7': [self.create_variable()],
                                              'a:8': [self.create_variable()],
                                              'a:9': [self.create_variable()],
                                              'a:10': [self.create_variable()],
                                              'a:11': [self.create_variable()],
                                              'a:12': [self.create_variable()],
                                              'a:13': [self.create_variable()],
                                              'a:14': [self.create_variable()],
                                              'a:15': [self.create_variable()],
                                              'a:16': [self.create_variable()],
                                              'a:17': [self.create_variable()],
                                              'a:18': [self.create_variable()],
                                              'a:19': [self.create_variable()],
                                              'a:20': [self.create_variable()],
                                              'a:000':
                                              [self.create_variable()],
                                          }),
                        self.create_scope(ScopeVisibility.FUNCTION_LOCAL,
                                          variables={
                                              'l:': [self.create_variable()],
                                              'a:': [self.create_variable()],
                                              'a:param_var1':
                                              [self.create_variable()],
                                              'a:0': [self.create_variable()],
                                              'a:1': [self.create_variable()],
                                              'a:2': [self.create_variable()],
                                              'a:3': [self.create_variable()],
                                              'a:4': [self.create_variable()],
                                              'a:5': [self.create_variable()],
                                              'a:6': [self.create_variable()],
                                              'a:7': [self.create_variable()],
                                              'a:8': [self.create_variable()],
                                              'a:9': [self.create_variable()],
                                              'a:10': [self.create_variable()],
                                              'a:11': [self.create_variable()],
                                              'a:12': [self.create_variable()],
                                              'a:13': [self.create_variable()],
                                              'a:14': [self.create_variable()],
                                              'a:15': [self.create_variable()],
                                              'a:16': [self.create_variable()],
                                              'a:17': [self.create_variable()],
                                              'a:18': [self.create_variable()],
                                              'a:19': [self.create_variable()],
                                              'a:000':
                                              [self.create_variable()],
                                          }),
                        self.create_scope(ScopeVisibility.FUNCTION_LOCAL,
                                          variables={
                                              'l:': [self.create_variable()],
                                              'a:': [self.create_variable()],
                                              'a:param':
                                              [self.create_variable()],
                                              'a:0': [self.create_variable()],
                                              'a:000':
                                              [self.create_variable()],
                                              'a:firstline':
                                              [self.create_variable()],
                                              'a:lastline':
                                              [self.create_variable()],
                                          }),
                        self.create_scope(ScopeVisibility.FUNCTION_LOCAL,
                                          variables={
                                              'l:': [self.create_variable()],
                                              'l:self':
                                              [self.create_variable()],
                                              'a:': [self.create_variable()],
                                              'a:0': [self.create_variable()],
                                              'a:000':
                                              [self.create_variable()],
                                          }),
                    ])
            ])

        self.assertScopeTreeEqual(expected_scope_tree, linker.scope_tree)
 def __init__(self):
     self._scope_linker = ScopeLinker()  # type: ScopeLinker
Exemplo n.º 30
0
class ReferenceReachabilityTester(object):
    """ A class for tester for reference reachability. """

    class TwoWayScopeReferenceAttacher(object):
        """ A class for AST processor to do attach to way reference between
        a parent scope and the child scopes.
        """

        @classmethod
        def attach(cls, root_scope_tree):
            # type: (Scope) -> Scope
            root_scope_tree.parent = None

            return cls._attach_recursively(root_scope_tree)


        @classmethod
        def _attach_recursively(cls, scope_tree):
            # type: (Scope) -> Scope
            for child_scope in scope_tree.child_scopes:
                child_scope.parent = scope_tree
                cls._attach_recursively(child_scope)

            return scope_tree


    def __init__(self):
        self._scope_linker = ScopeLinker()  # type: ScopeLinker


    def process(self, ast):
        self._scope_linker.process(ast)

        id_collector = IdentifierClassifier.IdentifierCollector()
        classified_id_group = id_collector.collect_identifiers(ast)
        dec_id_nodes = classified_id_group.statically_declared_identifiers
        ref_id_nodes = classified_id_group.statically_referencing_identifiers

        # Attach a parent_scope accessor to the scope tree
        ReferenceReachabilityTester.TwoWayScopeReferenceAttacher.attach(self._scope_linker.scope_tree)

        # Reset REFERENCED_FLAG to False
        for dec_id_node in dec_id_nodes:
            dec_id_node[REFERENCED_FLAG] = False

        for ref_id_node in ref_id_nodes:
            is_reachable = self.check_reachability(ref_id_node)
            ref_id_node[REACHABILITY_FLAG] = is_reachable


    def get_objective_scope_visibility(self, decl_or_ref_id_node):  # type: (Dict[str, Any]) -> ScopeVisibilityHint
        """ Returns a objective scope visibility by a declarative identifier node or a reference identifier node. """
        context_scope = self._scope_linker.link_registry.get_context_scope_by_identifier(decl_or_ref_id_node)
        possible_visibility_hint = detect_possible_scope_visibility(decl_or_ref_id_node, context_scope)
        possible_explicity = possible_visibility_hint.explicity

        # Return the visibility soon if the node already have a determined visibility.
        if possible_explicity is not ExplicityOfScopeVisibility.IMPLICIT_OR_LAMBDA:
            determined_visibility_hint = possible_visibility_hint
            return determined_visibility_hint

        # The node have IMPLICIT_OR_LAMBDA can be only reference identifier nodes.
        # SEE: detect_possible_scope_visibility
        ref_id_node = decl_or_ref_id_node

        # It is constrained implicit if it is a lambda argument.
        if self._is_reference_to_lambda_argument(ref_id_node):
            return ScopeVisibilityHint(
                scope_visibility=possible_visibility_hint.scope_visibility,
                explicity=ExplicityOfScopeVisibility.IMPLICIT_BUT_CONSTRAINED,
            )

        # Otherwise it is implicit.
        return ScopeVisibilityHint(
            scope_visibility=possible_visibility_hint.scope_visibility,
            explicity=ExplicityOfScopeVisibility.IMPLICIT
        )



    def _reset_referenced_flag(self, scope_tree):  # type: (Scope) -> None
        for child_scope in scope_tree.child_scopes:
            for functions in child_scope.functions.values():
                for func in functions:
                    decl_id_node = self._scope_linker.link_registry.get_declarative_identifier_by_variable(func)
                    decl_id_node[REFERENCED_FLAG] = False

            for variables in child_scope.variables.values():
                for variable in variables:
                    decl_id_node = self._scope_linker.link_registry.get_declarative_identifier_by_variable(variable)
                    decl_id_node[REFERENCED_FLAG] = False

            self._reset_referenced_flag(child_scope)


    def get_referenced_variable_declarations(self, ref_id_node):
        # type: (Dict[str, Any]) -> Union[List[VariableDeclaration], GlobalVariableDeclaration]

        scope = self._scope_linker.link_registry.get_context_scope_by_identifier(ref_id_node)
        var_name = remove_optional_scope_prefix(ref_id_node['value'])
        is_func_id = is_function_identifier(ref_id_node)

        while scope is not None:
            if is_func_id:
                functions_list = scope.functions
                if var_name in functions_list:
                    # The function is found in the symbol table for functions.
                    funcs = functions_list[var_name]

                    for func in funcs:
                        declaring_id_node = self._scope_linker.link_registry \
                            .get_declarative_identifier_by_variable(func)
                        declaring_id_node[REFERENCED_FLAG] = True

                    return funcs
                else:
                    # We can access the function via a variable function
                    # reference if the function not found from the symbol table
                    # for functions. So we should check the symbol table for
                    # variables to search the function reference.
                    pass

            variables_list = scope.variables
            if var_name in variables_list:
                # The variable or function reference found in the symbol table
                # for variables.
                variables = variables_list[var_name]

                for variable in variables:
                    declaring_id_node = self._scope_linker.link_registry \
                        .get_declarative_identifier_by_variable(variable)
                    declaring_id_node[REFERENCED_FLAG] = True

                return variables

            scope = scope.parent

        # If it is builtin, it will be used by Vim.
        if is_builtin_variable(ref_id_node):
            return GLOBAL_VARIABLE_DECLARATION

        return []


    def check_reachability(self, ref_id_node):  # type: (Dict[str, Any]) -> bool
        # NOTE: We can only assume dynamic identifiers can reach.
        if is_dynamic_identifier(ref_id_node):
            return True

        declarative_variables_or_global = self.get_referenced_variable_declarations(ref_id_node)

        if isinstance(declarative_variables_or_global, GlobalVariableDeclaration):
            # NOTE: It is a global like variable, so we can only assume it can reach.
            return True

        # NOTE: It is reachable if at least one declarative identifier can reach to found.
        return len(declarative_variables_or_global) > 0


    def _is_reference_to_lambda_argument(self, ref_id_node):  # type: (Dict[str, Any]) -> bool
        # NOTE: We can only assume dynamic identifiers can reach.
        if is_dynamic_identifier(ref_id_node):
            return True

        declarative_variables_or_global = self.get_referenced_variable_declarations(ref_id_node)

        if isinstance(declarative_variables_or_global, GlobalVariableDeclaration):
            return False

        declarative_variables = declarative_variables_or_global

        for declarative_variable in declarative_variables:
            if declarative_variable.is_explicit_lambda_argument:
                return True

        return False
Exemplo n.º 31
0
 def __init__(self):
     self._scope_linker = ScopeLinker()  # type: ScopeLinker