def dependencies_from_ast(self, tree):
        result = []

        if tree.type in ('file', 'function', 'catch'):
            top_scope = tree.scope
        else:
            top_scope = scopes.find_enclosing(tree)
        # walk through enclosing and all nested scopes
        for scope in top_scope.scope_iterator():
            if scope.is_defer:
                # e.g. in 'defer' handle locals like 'statics' as dependency with recursion
                vars_ = dict(scope.globals().items() +
                             [(x, y) for x, y in scope.locals().items()
                              if y.is_param])
            else:
                # only consider global syms
                vars_ = scope.globals()
            for name, scopeVar in vars_.items():  # { sym_name: ScopeVar }
                # create a depsItem for all its uses
                for var_node in scopeVar.uses:
                    if treeutil.hasAncestor(
                            var_node, tree
                    ):  # var_node is not disconnected through optimization
                        #depsItem = self.depsItem_from_node(var_node)
                        #result.append(depsItem)
                        result.append(var_node)
        return result
    def _analyzeClassDepsNode_2(self,
                                node,
                                depsList,
                                inLoadContext,
                                inDefer=False):
        if node.type in ('file', 'function', 'catch'):
            top_scope = node.scope
        else:
            top_scope = scopes.find_enclosing(
                node)  # get enclosing scope of node
        for scope in top_scope.scope_iterator(
        ):  # walk through this and all nested scopes
            for global_name, scopeVar in scope.globals().items(
            ):  # get the global symbols { sym_name: ScopeVar }
                for var_node in scopeVar.uses:  # create a depsItem for all its uses
                    if treeutil.hasAncestor(
                            var_node, node
                    ):  # var_node is not disconnected through optimization
                        depsItem = self.qualify_deps_item(
                            var_node, scope.is_load_time, scope.is_defer)
                        # as this also does filtering
                        if depsItem:
                            depsList.append(depsItem)  # and qualify them
                            #if depsItem.name == "qx.log.appender.Console":
                            #    import pydb; pydb.debugger()

        # Augment with feature dependencies introduces with qx.core.Environment.get("...") calls
        for env_operand in variantoptimizer.findVariantNodes(node):
            call_node = env_operand.parent.parent
            env_key = call_node.getChild("arguments").children[0].get(
                "value", "")
            className, classAttribute = self.getClassNameFromEnvKey(env_key)
            if className:
                #print className
                depsItem = DependencyItem(className, classAttribute, self.id,
                                          env_operand.get('line', -1))
                depsItem.isCall = True  # treat as if actual call, to collect recursive deps
                # .inLoadContext
                # get 'qx' node of 'qx.core.Environment....'
                qx_idnode = treeutil.findFirstChainChild(env_operand)
                scope = qx_idnode.scope
                inLoadContext = scope.is_load_time  # get its scope's .is_load_time
                depsItem.isLoadDep = inLoadContext
                if inLoadContext:
                    depsItem.needsRecursion = True
                depsList.append(depsItem)

        return
    def dependencies_from_ast(self, tree):
        result = []

        if tree.type in ("file", "function", "catch"):
            top_scope = tree.scope
        else:
            top_scope = scopes.find_enclosing(tree)
        # walk through enclosing and all nested scopes
        for scope in top_scope.scope_iterator():
            if scope.is_defer:
                # e.g. in 'defer' handle locals like 'statics' as dependency with recursion
                vars_ = dict(scope.globals().items() + [(x, y) for x, y in scope.locals().items() if y.is_param])
            else:
                # only consider global syms
                vars_ = scope.globals()
            for name, scopeVar in vars_.items():  # { sym_name: ScopeVar }
                # create a depsItem for all its uses
                for var_node in scopeVar.uses:
                    if treeutil.hasAncestor(var_node, tree):  # var_node is not disconnected through optimization
                        depsItem = self.depsItem_from_node(var_node)
                        result.append(depsItem)
        return result
    def _analyzeClassDepsNode_2(self, node, depsList, inLoadContext, inDefer=False):
        if node.type in ('file', 'function', 'catch'):
            top_scope = node.scope
        else:
            top_scope = scopes.find_enclosing(node)  # get enclosing scope of node
        for scope in top_scope.scope_iterator(): # walk through this and all nested scopes
            for global_name, scopeVar in scope.globals().items():  # get the global symbols { sym_name: ScopeVar }
                for var_node in scopeVar.uses:       # create a depsItem for all its uses
                    if treeutil.hasAncestor(var_node, node): # var_node is not disconnected through optimization
                        depsItem = self.qualify_deps_item(var_node, scope.is_load_time, scope.is_defer)
                        # as this also does filtering
                        if depsItem:
                            depsList.append(depsItem)    # and qualify them
                            #if depsItem.name == "qx.log.appender.Console":
                            #    import pydb; pydb.debugger()

        # Augment with feature dependencies introduces with qx.core.Environment.get("...") calls
        for env_operand in variantoptimizer.findVariantNodes(node):
            call_node = env_operand.parent.parent
            env_key = call_node.getChild("arguments").children[0].get("value", "")
            className, classAttribute = self.getClassNameFromEnvKey(env_key)
            if className:
                #print className
                depsItem = DependencyItem(className, classAttribute, self.id, env_operand.get('line', -1))
                depsItem.isCall = True  # treat as if actual call, to collect recursive deps
                # .inLoadContext
                # get 'qx' node of 'qx.core.Environment....'
                qx_idnode = treeutil.findFirstChainChild(env_operand)
                scope = qx_idnode.scope
                inLoadContext = scope.is_load_time # get its scope's .is_load_time
                depsItem.isLoadDep = inLoadContext
                if inLoadContext:
                    depsItem.needsRecursion = True
                depsList.append(depsItem)

        return