def find_usages_in_node(node, global_encountered=False):
            names = []
            if isinstance(node, tree.BaseNode):
                if parser_utils.is_scope(node):
                    global_encountered = False
                    if node in searched_scopes:
                        return names
                    searched_scopes.add(node)
                    if isinstance(node, tree.Function):
                        d = self._get_def_from_function_params(node, name)
                        if d and d != definition:
                            return []

                for c in node.children:
                    dot_names = self._get_dot_names(c)
                    if len(dot_names) > 1 and dot_names[1].value == name.value:
                        continue
                    sub_result = find_usages_in_node(c, global_encountered=global_encountered)

                    if sub_result is None:
                        if not parser_utils.is_scope(node):
                            return (
                                None
                                if definition and node != parser_utils.get_parent_scope(definition)
                                else [definition]
                            )
                        else:
                            sub_result = []
                    names.extend(sub_result)
                    if self._is_global_stmt_with_name(c, name.value):
                        global_encountered = True
            elif isinstance(node, tree.Name) and node.value == name.value:
                if definition and definition != node:
                    if self._is_name_function_definition(node):
                        if isinstance(
                            parser_utils.get_parent_scope(parser_utils.get_parent_scope(node)),
                            tree.Class,
                        ):
                            return []
                        else:
                            return None
                    if (
                        node.is_definition()
                        and not global_encountered
                        and (
                            is_function_definition
                            or parser_utils.get_parent_scope(node)
                            != parser_utils.get_parent_scope(definition)
                        )
                    ):
                        return None
                    if self._is_name_function_definition(definition) and isinstance(
                        parser_utils.get_parent_scope(parser_utils.get_parent_scope(definition)),
                        tree.Class,
                    ):
                        return None
                names.append(node)
            return names
Beispiel #2
0
    def filter_name(self, filters):
        """
        Searches names that are defined in a scope (the different
        ``filters``), until a name fits.
        """
        names = []
        if self._context.predefined_names:
            # TODO is this ok? node might not always be a tree.Name
            node = self._name
            while node is not None and not is_scope(node):
                node = node.parent
                if node.type in ("if_stmt", "for_stmt", "comp_for"):
                    try:
                        name_dict = self._context.predefined_names[node]
                        types = name_dict[self._string_name]
                    except KeyError:
                        continue
                    else:
                        self._found_predefined_types = types
                        break

        for filter in filters:
            names = filter.get(self._string_name)
            if names:
                break
        debug.dbg('finder.filter_name "%s" in (%s): %s@%s', self._string_name,
                  self._context, names, self._position)
        return list(names)
Beispiel #3
0
    def filter_name(self, filters):
        """
        Searches names that are defined in a scope (the different
        ``filters``), until a name fits.
        """
        names = []
        if self._context.predefined_names:
            # TODO is this ok? node might not always be a tree.Name
            node = self._name
            while node is not None and not is_scope(node):
                node = node.parent
                if node.type in ("if_stmt", "for_stmt", "comp_for"):
                    try:
                        name_dict = self._context.predefined_names[node]
                        types = name_dict[self._string_name]
                    except KeyError:
                        continue
                    else:
                        self._found_predefined_types = types
                        break

        for filter in filters:
            names = filter.get(self._string_name)
            if names:
                break
        debug.dbg('finder.filter_name "%s" in (%s): %s@%s', self._string_name,
                  self._context, names, self._position)
        return list(names)
Beispiel #4
0
def is_scope(node):
    try:
        # jedi 0.11
        from jedi import parser_utils
        return parser_utils.is_scope(node)
    except ImportError:
        # Older versions
        return node.is_scope()
Beispiel #5
0
    def py__getattribute__(self,
                           name_or_str,
                           name_context=None,
                           position=None,
                           analysis_errors=True):
        """
        :param position: Position of the last statement -> tuple of line, column
        """
        if name_context is None:
            name_context = self
        names = self.goto(name_or_str, position)

        string_name = name_or_str.value if isinstance(name_or_str,
                                                      Name) else name_or_str

        # This paragraph is currently needed for proper branch type inference
        # (static analysis).
        found_predefined_types = None
        if self.predefined_names and isinstance(name_or_str, Name):
            node = name_or_str
            while node is not None and not parser_utils.is_scope(node):
                node = node.parent
                if node.type in ("if_stmt", "for_stmt", "comp_for",
                                 'sync_comp_for'):
                    try:
                        name_dict = self.predefined_names[node]
                        types = name_dict[string_name]
                    except KeyError:
                        continue
                    else:
                        found_predefined_types = types
                        break
        if found_predefined_types is not None and names:
            from jedi.inference import flow_analysis
            check = flow_analysis.reachability_check(
                context=self,
                value_scope=self.tree_node,
                node=name_or_str,
            )
            if check is flow_analysis.UNREACHABLE:
                values = NO_VALUES
            else:
                values = found_predefined_types
        else:
            values = ValueSet.from_sets(name.infer() for name in names)

        if not names and not values and analysis_errors:
            if isinstance(name_or_str, Name):
                from jedi.inference import analysis
                message = ("NameError: name '%s' is not defined." %
                           string_name)
                analysis.add(name_context, 'name-error', name_or_str, message)

        debug.dbg('context.names_to_types: %s -> %s', names, values)
        if values:
            return values
        return self._check_for_additional_knowledge(name_or_str, name_context,
                                                    position)
Beispiel #6
0
    def create_context(self, base_context, node, node_is_context=False, node_is_object=False):
        def parent_scope(node):
            while True:
                node = node.parent

                if parser_utils.is_scope(node):
                    return node
                elif node.type in ('argument', 'testlist_comp'):
                    if node.children[1].type == 'comp_for':
                        return node.children[1]
                elif node.type == 'dictorsetmaker':
                    for n in node.children[1:4]:
                        # In dictionaries it can be pretty much anything.
                        if n.type == 'comp_for':
                            return n

        def from_scope_node(scope_node, is_nested=True, node_is_object=False):
            if scope_node == base_node:
                return base_context

            is_funcdef = scope_node.type in ('funcdef', 'lambdef')
            parent_scope = parser_utils.get_parent_scope(scope_node)
            parent_context = from_scope_node(parent_scope)

            if is_funcdef:
                func = FunctionContext.from_context(parent_context, scope_node)
                if parent_context.is_class():
                    instance = AnonymousInstance(
                        self, parent_context.parent_context, parent_context)
                    func = BoundMethod(
                        instance=instance,
                        function=func
                    )

                if is_nested and not node_is_object:
                    return func.get_function_execution()
                return func
            elif scope_node.type == 'classdef':
                return ClassContext(self, parent_context, scope_node)
            elif scope_node.type == 'comp_for':
                if node.start_pos >= scope_node.children[-1].start_pos:
                    return parent_context
                return CompForContext.from_comp_for(parent_context, scope_node)
            raise Exception("There's a scope that was not managed.")

        base_node = base_context.tree_node

        if node_is_context and parser_utils.is_scope(node):
            scope_node = node
        else:
            scope_node = parent_scope(node)
            if scope_node.type in ('funcdef', 'classdef'):
                colon = scope_node.children[scope_node.children.index(':')]
                if node.start_pos < colon.start_pos:
                    parent = node.parent
                    if not (parent.type == 'param' and parent.name == node):
                        scope_node = parent_scope(scope_node)
        return from_scope_node(scope_node, is_nested=True, node_is_object=node_is_object)
Beispiel #7
0
        def parent_scope(node):
            while True:
                node = node.parent

                if parser_utils.is_scope(node):
                    return node
                elif node.type in ('argument', 'testlist_comp'):
                    if node.children[1].type == 'comp_for':
                        return node.children[1]
                elif node.type == 'dictorsetmaker':
                    for n in node.children[1:4]:
                        # In dictionaries it can be pretty much anything.
                        if n.type == 'comp_for':
                            return n
Beispiel #8
0
        def parent_scope(node):
            while True:
                node = node.parent

                if parser_utils.is_scope(node):
                    return node
                elif node.type in ('argument', 'testlist_comp'):
                    if node.children[1].type == 'comp_for':
                        return node.children[1]
                elif node.type == 'dictorsetmaker':
                    for n in node.children[1:4]:
                        # In dictionaries it can be pretty much anything.
                        if n.type == 'comp_for':
                            return n
    def filter_name(self, filters):
        """
        Searches names that are defined in a scope (the different
        ``filters``), until a name fits.
        """
        names = []
        # This paragraph is currently needed for proper branch evaluation
        # (static analysis).
        if self._context.predefined_names and isinstance(
                self._name, tree.Name):
            node = self._name
            while node is not None and not is_scope(node):
                node = node.parent
                if node.type in ("if_stmt", "for_stmt", "comp_for",
                                 'sync_comp_for'):
                    try:
                        name_dict = self._context.predefined_names[node]
                        types = name_dict[self._string_name]
                    except KeyError:
                        continue
                    else:
                        self._found_predefined_types = types
                        break

        for filter in filters:
            names = filter.get(self._string_name)
            if names:
                if len(names) == 1:
                    n, = names
                    if isinstance(n, TreeNameDefinition):
                        # Something somewhere went terribly wrong. This
                        # typically happens when using goto on an import in an
                        # __init__ file. I think we need a better solution, but
                        # it's kind of hard, because for Jedi it's not clear
                        # that that name has not been defined, yet.
                        if n.tree_name == self._name:
                            def_ = self._name.get_definition()
                            if def_ is not None and def_.type == 'import_from':
                                continue
                break

        debug.dbg('finder.filter_name %s in (%s): %s@%s', self._string_name,
                  self._context, names, self._position)
        return list(names)
Beispiel #10
0
    def filter_name(self, filters):
        """
        Searches names that are defined in a scope (the different
        ``filters``), until a name fits.
        """
        names = []
        if self._context.predefined_names:
            # TODO is this ok? node might not always be a tree.Name
            node = self._name
            while node is not None and not is_scope(node):
                node = node.parent
                if node.type in ("if_stmt", "for_stmt", "comp_for"):
                    try:
                        name_dict = self._context.predefined_names[node]
                        types = name_dict[self._string_name]
                    except KeyError:
                        continue
                    else:
                        self._found_predefined_types = types
                        break

        for filter in filters:
            names = filter.get(self._string_name)
            if names:
                if len(names) == 1:
                    n, = names
                    if isinstance(n, TreeNameDefinition):
                        # Something somewhere went terribly wrong. This
                        # typically happens when using goto on an import in an
                        # __init__ file. I think we need a better solution, but
                        # it's kind of hard, because for Jedi it's not clear
                        # that that name has not been defined, yet.
                        if n.tree_name == self._name:
                            if self._name.get_definition().type == 'import_from':
                                continue
                break

        debug.dbg('finder.filter_name "%s" in (%s): %s@%s', self._string_name,
                  self._context, names, self._position)
        return list(names)
Beispiel #11
0
def _check_flow_information(context, flow, search_name, pos):
    """ Try to find out the type of a variable just with the information that
    is given by the flows: e.g. It is also responsible for assert checks.::

        if isinstance(k, str):
            k.  # <- completion here

    ensures that `k` is a string.
    """
    if not settings.dynamic_flow_information:
        return None

    result = None
    if is_scope(flow):
        # Check for asserts.
        module_node = flow.get_root_node()
        try:
            names = module_node.get_used_names()[search_name.value]
        except KeyError:
            return None
        names = reversed([
            n for n in names
            if flow.start_pos <= n.start_pos < (pos or flow.end_pos)
        ])

        for name in names:
            ass = search_ancestor(name, 'assert_stmt')
            if ass is not None:
                result = _check_isinstance_type(context, ass.assertion,
                                                search_name)
                if result is not None:
                    return result

    if flow.type in ('if_stmt', 'while_stmt'):
        potential_ifs = [c for c in flow.children[1::4] if c != ':']
        for if_test in reversed(potential_ifs):
            if search_name.start_pos > if_test.end_pos:
                return _check_isinstance_type(context, if_test, search_name)
    return result
Beispiel #12
0
def _check_flow_information(context, flow, search_name, pos):
    """ Try to find out the type of a variable just with the information that
    is given by the flows: e.g. It is also responsible for assert checks.::

        if isinstance(k, str):
            k.  # <- completion here

    ensures that `k` is a string.
    """
    if not settings.dynamic_flow_information:
        return None

    result = None
    if is_scope(flow):
        # Check for asserts.
        module_node = flow.get_root_node()
        try:
            names = module_node.get_used_names()[search_name.value]
        except KeyError:
            return None
        names = reversed([
            n for n in names
            if flow.start_pos <= n.start_pos < (pos or flow.end_pos)
        ])

        for name in names:
            ass = search_ancestor(name, 'assert_stmt')
            if ass is not None:
                result = _check_isinstance_type(context, ass.assertion, search_name)
                if result is not None:
                    return result

    if flow.type in ('if_stmt', 'while_stmt'):
        potential_ifs = [c for c in flow.children[1::4] if c != ':']
        for if_test in reversed(potential_ifs):
            if search_name.start_pos > if_test.end_pos:
                return _check_isinstance_type(context, if_test, search_name)
    return result
Beispiel #13
0
    def get_positions(self):
        import parso
        from jedi import parser_utils
        from parso.python import tree

        locs = []

        def process_scope(scope):
            if isinstance(scope, tree.Function):
                # process all children after name node,
                # (otherwise name of global function will be marked as local def)
                local_names = set()
                global_names = set()
                for child in scope.children[2:]:
                    process_node(child, local_names, global_names)
            else:
                if hasattr(scope, "subscopes"):
                    for child in scope.subscopes:
                        process_scope(child)
                elif hasattr(scope, "children"):
                    for child in scope.children:
                        process_scope(child)

        def process_node(node, local_names, global_names):
            if isinstance(node, tree.GlobalStmt):
                global_names.update([n.value for n in node.get_global_names()])

            elif isinstance(node, tree.Name):
                if node.value in global_names:
                    return

                if node.is_definition():  # local def
                    locs.append(node)
                    local_names.add(node.value)
                elif node.value in local_names:  # use of local
                    locs.append(node)

            elif isinstance(node, tree.BaseNode):
                # ref: jedi/parser/grammar*.txt
                if node.type == "trailer" and node.children[0].value == ".":
                    # this is attribute
                    return

                if isinstance(node, tree.Function):
                    global_names = set(
                    )  # outer global statement doesn't have effect anymore

                for child in node.children:
                    process_node(child, local_names, global_names)

        source = self.text.get("1.0", "end")
        module = parso.parse(source)
        for child in module.children:
            if isinstance(child,
                          tree.BaseNode) and parser_utils.is_scope(child):
                process_scope(child)

        loc_pos = set((
            "%d.%d" % (usage.start_pos[0], usage.start_pos[1]),
            "%d.%d" %
            (usage.start_pos[0], usage.start_pos[1] + len(usage.value)),
        ) for usage in locs)

        return loc_pos
Beispiel #14
0
def infer_node(context, element):
    if isinstance(context, CompForContext):
        return _infer_node(context, element)

    if_stmt = element
    while if_stmt is not None:
        if_stmt = if_stmt.parent
        if if_stmt.type in ('if_stmt', 'for_stmt'):
            break
        if parser_utils.is_scope(if_stmt):
            if_stmt = None
            break
    predefined_if_name_dict = context.predefined_names.get(if_stmt)
    # TODO there's a lot of issues with this one. We actually should do
    # this in a different way. Caching should only be active in certain
    # cases and this all sucks.
    if predefined_if_name_dict is None and if_stmt \
            and if_stmt.type == 'if_stmt' and context.inference_state.is_analysis:
        if_stmt_test = if_stmt.children[1]
        name_dicts = [{}]
        # If we already did a check, we don't want to do it again -> If
        # value.predefined_names is filled, we stop.
        # We don't want to check the if stmt itself, it's just about
        # the content.
        if element.start_pos > if_stmt_test.end_pos:
            # Now we need to check if the names in the if_stmt match the
            # names in the suite.
            if_names = get_names_of_node(if_stmt_test)
            element_names = get_names_of_node(element)
            str_element_names = [e.value for e in element_names]
            if any(i.value in str_element_names for i in if_names):
                for if_name in if_names:
                    definitions = context.inference_state.infer(
                        context, if_name)
                    # Every name that has multiple different definitions
                    # causes the complexity to rise. The complexity should
                    # never fall below 1.
                    if len(definitions) > 1:
                        if len(name_dicts) * len(definitions) > 16:
                            debug.dbg(
                                'Too many options for if branch inference %s.',
                                if_stmt)
                            # There's only a certain amount of branches
                            # Jedi can infer, otherwise it will take to
                            # long.
                            name_dicts = [{}]
                            break

                        original_name_dicts = list(name_dicts)
                        name_dicts = []
                        for definition in definitions:
                            new_name_dicts = list(original_name_dicts)
                            for i, name_dict in enumerate(new_name_dicts):
                                new_name_dicts[i] = name_dict.copy()
                                new_name_dicts[i][if_name.value] = ValueSet(
                                    [definition])

                            name_dicts += new_name_dicts
                    else:
                        for name_dict in name_dicts:
                            name_dict[if_name.value] = definitions
        if len(name_dicts) > 1:
            result = NO_VALUES
            for name_dict in name_dicts:
                with context.predefine_names(if_stmt, name_dict):
                    result |= _infer_node(context, element)
            return result
        else:
            return _infer_node_if_inferred(context, element)
    else:
        if predefined_if_name_dict:
            return _infer_node(context, element)
        else:
            return _infer_node_if_inferred(context, element)
Beispiel #15
0
    def eval_element(self, context, element):
        if isinstance(context, iterable.CompForContext):
            return self._eval_element_not_cached(context, element)

        if_stmt = element
        while if_stmt is not None:
            if_stmt = if_stmt.parent
            if if_stmt.type in ('if_stmt', 'for_stmt'):
                break
            if parser_utils.is_scope(if_stmt):
                if_stmt = None
                break
        predefined_if_name_dict = context.predefined_names.get(if_stmt)
        if predefined_if_name_dict is None and if_stmt and if_stmt.type == 'if_stmt':
            if_stmt_test = if_stmt.children[1]
            name_dicts = [{}]
            # If we already did a check, we don't want to do it again -> If
            # context.predefined_names is filled, we stop.
            # We don't want to check the if stmt itself, it's just about
            # the content.
            if element.start_pos > if_stmt_test.end_pos:
                # Now we need to check if the names in the if_stmt match the
                # names in the suite.
                if_names = helpers.get_names_of_node(if_stmt_test)
                element_names = helpers.get_names_of_node(element)
                str_element_names = [e.value for e in element_names]
                if any(i.value in str_element_names for i in if_names):
                    for if_name in if_names:
                        definitions = self.goto_definitions(context, if_name)
                        # Every name that has multiple different definitions
                        # causes the complexity to rise. The complexity should
                        # never fall below 1.
                        if len(definitions) > 1:
                            if len(name_dicts) * len(definitions) > 16:
                                debug.dbg('Too many options for if branch evaluation %s.', if_stmt)
                                # There's only a certain amount of branches
                                # Jedi can evaluate, otherwise it will take to
                                # long.
                                name_dicts = [{}]
                                break

                            original_name_dicts = list(name_dicts)
                            name_dicts = []
                            for definition in definitions:
                                new_name_dicts = list(original_name_dicts)
                                for i, name_dict in enumerate(new_name_dicts):
                                    new_name_dicts[i] = name_dict.copy()
                                    new_name_dicts[i][if_name.value] = set([definition])

                                name_dicts += new_name_dicts
                        else:
                            for name_dict in name_dicts:
                                name_dict[if_name.value] = definitions
            if len(name_dicts) > 1:
                result = set()
                for name_dict in name_dicts:
                    with helpers.predefine_names(context, if_stmt, name_dict):
                        result |= self._eval_element_not_cached(context, element)
                return result
            else:
                return self._eval_element_if_evaluated(context, element)
        else:
            if predefined_if_name_dict:
                return self._eval_element_not_cached(context, element)
            else:
                return self._eval_element_if_evaluated(context, element)
def _get_flow_scopes(node):
    while True:
        node = get_parent_scope(node, include_flows=True)
        if node is None or is_scope(node):
            return
        yield node
Beispiel #17
0
def _get_flow_scopes(node):
    while True:
        node = get_parent_scope(node, include_flows=True)
        if node is None or is_scope(node):
            return
        yield node
Beispiel #18
0
    def create_context(self, base_context, node, node_is_context=False, node_is_object=False):
        def parent_scope(node):
            while True:
                node = node.parent

                if parser_utils.is_scope(node):
                    return node
                elif node.type in ('argument', 'testlist_comp'):
                    if node.children[1].type == 'comp_for':
                        return node.children[1]
                elif node.type == 'dictorsetmaker':
                    for n in node.children[1:4]:
                        # In dictionaries it can be pretty much anything.
                        if n.type == 'comp_for':
                            return n

        def from_scope_node(scope_node, child_is_funcdef=None, is_nested=True, node_is_object=False):
            if scope_node == base_node:
                return base_context

            is_funcdef = scope_node.type in ('funcdef', 'lambdef')
            parent_scope = parser_utils.get_parent_scope(scope_node)
            parent_context = from_scope_node(parent_scope, child_is_funcdef=is_funcdef)

            if is_funcdef:
                if isinstance(parent_context, AnonymousInstance):
                    func = BoundMethod(
                        self, parent_context, parent_context.class_context,
                        parent_context.parent_context, scope_node
                    )
                else:
                    func = FunctionContext(
                        self,
                        parent_context,
                        scope_node
                    )
                if is_nested and not node_is_object:
                    return func.get_function_execution()
                return func
            elif scope_node.type == 'classdef':
                class_context = ClassContext(self, parent_context, scope_node)
                if child_is_funcdef:
                    # anonymous instance
                    return AnonymousInstance(self, parent_context, class_context)
                else:
                    return class_context
            elif scope_node.type == 'comp_for':
                if node.start_pos >= scope_node.children[-1].start_pos:
                    return parent_context
                return CompForContext.from_comp_for(parent_context, scope_node)
            raise Exception("There's a scope that was not managed.")

        base_node = base_context.tree_node

        if node_is_context and parser_utils.is_scope(node):
            scope_node = node
        else:
            if node.parent.type in ('funcdef', 'classdef') and node.parent.name == node:
                # When we're on class/function names/leafs that define the
                # object itself and not its contents.
                node = node.parent
            scope_node = parent_scope(node)
        return from_scope_node(scope_node, is_nested=True, node_is_object=node_is_object)
Beispiel #19
0
    def eval_element(self, context, element):
        if isinstance(context, CompForContext):
            return eval_node(context, element)

        if_stmt = element
        while if_stmt is not None:
            if_stmt = if_stmt.parent
            if if_stmt.type in ('if_stmt', 'for_stmt'):
                break
            if parser_utils.is_scope(if_stmt):
                if_stmt = None
                break
        predefined_if_name_dict = context.predefined_names.get(if_stmt)
        # TODO there's a lot of issues with this one. We actually should do
        # this in a different way. Caching should only be active in certain
        # cases and this all sucks.
        if predefined_if_name_dict is None and if_stmt \
                and if_stmt.type == 'if_stmt' and self.is_analysis:
            if_stmt_test = if_stmt.children[1]
            name_dicts = [{}]
            # If we already did a check, we don't want to do it again -> If
            # context.predefined_names is filled, we stop.
            # We don't want to check the if stmt itself, it's just about
            # the content.
            if element.start_pos > if_stmt_test.end_pos:
                # Now we need to check if the names in the if_stmt match the
                # names in the suite.
                if_names = helpers.get_names_of_node(if_stmt_test)
                element_names = helpers.get_names_of_node(element)
                str_element_names = [e.value for e in element_names]
                if any(i.value in str_element_names for i in if_names):
                    for if_name in if_names:
                        definitions = self.goto_definitions(context, if_name)
                        # Every name that has multiple different definitions
                        # causes the complexity to rise. The complexity should
                        # never fall below 1.
                        if len(definitions) > 1:
                            if len(name_dicts) * len(definitions) > 16:
                                debug.dbg('Too many options for if branch evaluation %s.', if_stmt)
                                # There's only a certain amount of branches
                                # Jedi can evaluate, otherwise it will take to
                                # long.
                                name_dicts = [{}]
                                break

                            original_name_dicts = list(name_dicts)
                            name_dicts = []
                            for definition in definitions:
                                new_name_dicts = list(original_name_dicts)
                                for i, name_dict in enumerate(new_name_dicts):
                                    new_name_dicts[i] = name_dict.copy()
                                    new_name_dicts[i][if_name.value] = ContextSet(definition)

                                name_dicts += new_name_dicts
                        else:
                            for name_dict in name_dicts:
                                name_dict[if_name.value] = definitions
            if len(name_dicts) > 1:
                result = ContextSet()
                for name_dict in name_dicts:
                    with helpers.predefine_names(context, if_stmt, name_dict):
                        result |= eval_node(context, element)
                return result
            else:
                return self._eval_element_if_evaluated(context, element)
        else:
            if predefined_if_name_dict:
                return eval_node(context, element)
            else:
                return self._eval_element_if_evaluated(context, element)