def _analyzeClassDepsNode_1(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 # import pydb; pydb.debugger() 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 node in scopeVar.uses: # create a depsItem for all its uses depsItem = self.qualify_deps_item(node, scope.is_load_time, scope.is_defer) depsList.append(depsItem) # and qualify them # Augment with feature dependencies introduces with qx.core.Environment.get("...") calls for envCall in variantoptimizer.findVariantNodes(node): className, classAttribute = self.getClassNameFromEnvKey( envCall.getChild("arguments").children[0].get("value", "") ) if className: depsItem = DependencyItem(className, classAttribute, self.id, envCall.get("line", -1)) depsItem.isCall = True # treat as if actual call, to collect recursive deps # .inLoadContext # get 'qx' node of 'qx.core.Environment....' call_operand = envCall.getChild("operand").children[0] qx_idnode = treeutil.findFirstChainChild(call_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_envcalls(self, node): depsList = [] if 'qx.core.Environment' not in ClassesAll: self.context['console'].warn( "No qx.core.Environment available to extract feature keys from" ) return depsList qcEnvClass = ClassesAll['qx.core.Environment'] 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 = qcEnvClass.classNameFromEnvKey(env_key) if className and className in ClassesAll: #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 depsItem.node = call_node # .inLoadContext qx_idnode = treeutil.findFirstChainChild( env_operand) # 'qx' node of 'qx.core.Environment....' scope = qx_idnode.scope depsItem.isLoadDep = scope.is_load_time if depsItem.isLoadDep: depsItem.needsRecursion = True depsList.append(depsItem) return depsList
def depsItem_from_node(self, node): scope = node.scope # some initializations (might get refined later) depsItem = DependencyItem('', '', '') depsItem.name = '' depsItem.attribute = '' depsItem.requestor = self.id depsItem.line = node.get("line", -1) depsItem.isLoadDep = scope.is_load_time depsItem.needsRecursion = False depsItem.isCall = False depsItem.node = node var_root = treeutil.findVarRoot(node) # various of the tests need the var (dot) root, rather than the head symbol (like 'qx') # .isCall if treeutil.isCallOperand(var_root): # it's a function call or new op. depsItem.isCall = True # interesting when following transitive deps # .name, .attribute assembled = (treeutil.assembleVariable(node))[0] #className, classAttribute = self._splitQxClass(assembled) className = gs.test_for_libsymbol(assembled, ClassesAll, []) # TODO: no namespaces!? if not className: is_lib_class = False className = assembled classAttribute = '' else: is_lib_class = True if len(assembled) > len(className): classAttribute = assembled[len(className)+1:] else: classAttribute = '' # we allow self-references, to be able to track method dependencies within the same class assembled_parts = assembled.split('.') if assembled_parts[0] == 'this': className = self.id is_lib_class = True if '.' in assembled: classAttribute = assembled_parts[1] elif scope.is_defer and assembled_parts[0] in DEFER_ARGS: className = self.id is_lib_class = True if '.' in assembled: classAttribute = assembled_parts[1] if is_lib_class and not classAttribute: # see if we have to provide 'construct' if treeutil.isNEWoperand(var_root): classAttribute = 'construct' depsItem.name = className depsItem.attribute = classAttribute # .needsRecursion # Mark items that need recursive analysis of their dependencies (bug#1455) if (is_lib_class and scope.is_load_time and (treeutil.isCallOperand(var_root) or treeutil.isNEWoperand(var_root))): depsItem.needsRecursion = True return depsItem
def depsItem_from_node(self, node): scope = node.scope # some initializations (might get refined later) depsItem = DependencyItem('', '', '') depsItem.name = '' depsItem.attribute = '' depsItem.requestor = self.id depsItem.line = node.get("line", -1) depsItem.isLoadDep = scope.is_load_time depsItem.needsRecursion = False depsItem.isCall = False depsItem.node = node is_lib_class = False var_root = treeutil.findVarRoot(node) # various of the tests need the var (dot) root, rather than the head symbol (like 'qx') # .isCall if treeutil.isCallOperand(var_root): # it's a function call or new op. depsItem.isCall = True # interesting when following transitive deps # .name, .attribute assembled = (treeutil.assembleVariable(node))[0] className, classAttribute = self._splitQxClass(assembled) if not className: if "." in assembled: className, classAttribute = assembled.split('.')[:2] else: className = assembled else: is_lib_class = True # we allow self-references, to be able to track method dependencies within the same class if self.is_this(className): if className.find('.')>-1: classAttribute = className.split('.')[1] className = self.id is_lib_class = True elif scope.is_defer and className in DEFER_ARGS: className = self.id is_lib_class = True if is_lib_class and not classAttribute: # see if we have to provide 'construct' if treeutil.isNEWoperand(var_root): classAttribute = 'construct' depsItem.name = className depsItem.attribute = classAttribute # .needsRecursion # Mark items that need recursive analysis of their dependencies (bug#1455) #if self.followCallDeps(var_root, self.id, className, isLoadTime): #if self.id=='qx.bom.element.Style' and depsItem.attribute=='__detectVendorProperties': # import pydb; pydb.debugger() if (is_lib_class and scope.is_load_time and (treeutil.isCallOperand(var_root) or treeutil.isNEWoperand(var_root))): depsItem.needsRecursion = True return depsItem
def depsItems_from_Json(self, deps_json): result = {'run':[], 'load':[], 'ignore':[]} for category in ('run', 'load'): for classId in deps_json[category]: if any([classId.startswith(x) for x in ('/resource/', '/translation/', '/locale/')]): continue # sorting out resource, locale and msgid dependencies depsItem = DependencyItem(classId, '', '|dependency.json|') depsItem.isLoadDep = category == 'load' result[category].append(depsItem) return result
def depsItems_from_Json(self, deps_json): result = {'run':[], 'load':[], 'ignore':[]} for category in ('run', 'load'): for classId in deps_json[category]: if any([classId.startswith(x) for x in ('/resource/', '/translation/', '/locale/')]): continue # sorting out resource, locale and msgid dependencies depsItem = DependencyItem(classId, '', '|dependency.json|') depsItem.isLoadDep = category == 'load' result[category].append(depsItem) return result
def depsItems_from_Json(self, deps_json): result = {"run": [], "load": [], "ignore": []} for category in ("run", "load"): for classId in deps_json[category]: if any([classId.startswith(x) for x in ("/resource/", "/translation/", "/locale/")]): continue # sorting out resource, locale and msgid dependencies depsItem = DependencyItem(classId, "", "|dependency.json|") depsItem.isLoadDep = category == "load" result[category].append(depsItem) return result
def qualify_deps_item(self, node, isLoadTime, inDefer, depsItem=None): if not depsItem: depsItem = DependencyItem('', '', '') depsItem.name = '' depsItem.attribute = '' depsItem.requestor = self.id depsItem.line = node.get("line", -1) depsItem.isLoadDep = isLoadTime depsItem.needsRecursion = False depsItem.isCall = False var_root = treeutil.findVarRoot( node ) # various of the tests need the var (dot) root, rather than the head symbol (like 'qx') # .isCall if var_root.hasParentContext("call/operand"): # it's a function call depsItem.isCall = True # interesting when following transitive deps # .name assembled = (treeutil.assembleVariable(node))[0] _, className, classAttribute = self._isInterestingReference( assembled, var_root, self.id, inDefer) # postcond: # - className != '' must always be true, as we know it is an interesting reference # - might be a known qooxdoo class, or an unknown class (use 'className in self._classes') # - if assembled contained ".", classAttribute will contain approx. non-class part if className: # we allow self-references, to be able to track method dependencies within the same class if className == 'this': className = self.id elif inDefer and className in DEFER_ARGS: className = self.id if not classAttribute: # see if we have to provide 'construct' if treeutil.isNEWoperand(node): classAttribute = 'construct' # Can't do the next; it's catching too many occurrences of 'getInstance' that have # nothing to do with the singleton 'getInstance' method (just grep in the framework) #elif classAttribute == 'getInstance': # erase 'getInstance' and introduce 'construct' dependency # classAttribute = 'construct' depsItem.name = className depsItem.attribute = classAttribute # .needsRecursion # Mark items that need recursive analysis of their dependencies (bug#1455) if self.followCallDeps(var_root, self.id, className, isLoadTime): depsItem.needsRecursion = True if depsItem.name: return depsItem else: return None
def qualify_deps_item(self, node, isLoadTime, inDefer, depsItem=None): if not depsItem: depsItem = DependencyItem('', '', '') depsItem.name = '' depsItem.attribute = '' depsItem.requestor = self.id depsItem.line = node.get("line", -1) depsItem.isLoadDep = isLoadTime depsItem.needsRecursion = False depsItem.isCall = False var_root = treeutil.findVarRoot(node) # various of the tests need the var (dot) root, rather than the head symbol (like 'qx') # .isCall if var_root.hasParentContext("call/operand"): # it's a function call depsItem.isCall = True # interesting when following transitive deps # .name assembled = (treeutil.assembleVariable(node))[0] _, className, classAttribute = self._isInterestingReference(assembled, var_root, self.id, inDefer) # postcond: # - className != '' must always be true, as we know it is an interesting reference # - might be a known qooxdoo class, or an unknown class (use 'className in self._classes') # - if assembled contained ".", classAttribute will contain approx. non-class part if className: # we allow self-references, to be able to track method dependencies within the same class if className == 'this': className = self.id elif inDefer and className in DEFER_ARGS: className = self.id if not classAttribute: # see if we have to provide 'construct' if treeutil.isNEWoperand(node): classAttribute = 'construct' # Can't do the next; it's catching too many occurrences of 'getInstance' that have # nothing to do with the singleton 'getInstance' method (just grep in the framework) #elif classAttribute == 'getInstance': # erase 'getInstance' and introduce 'construct' dependency # classAttribute = 'construct' depsItem.name = className depsItem.attribute = classAttribute # .needsRecursion # Mark items that need recursive analysis of their dependencies (bug#1455) if self.followCallDeps(var_root, self.id, className, isLoadTime): depsItem.needsRecursion = True if depsItem.name: return depsItem else: return None
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 visit_call(self, node): #print "visiting", node.type if variantoptimizer.isEnvironmentCall(node): assert self.opts.envmappings key = treeutil.selectNode(node, "arguments/1") classname, methname = self.getClassNameFromEnvKey(key, self.opts.envmappings) if classname: depsItem = DependencyItem(classname, methname, self.file_name, node.get('line',0) or -1) depsItem.isCall = True # treat as if actual call, to collect recursive deps # check phase functor = node.getChild("operand") # get the "qx.core.Environment" symbol if self.is_static_loaddep(functor): depsItem.isLoadDep = True depsItem.needsRecursion = True self.deps.append(depsItem)
def visit_call(self, node): #print "visiting", node.type if variantoptimizer.isEnvironmentCall(node): assert self.opts.envmappings key = treeutil.selectNode(node, "arguments/1") classname, methname = self.getClassNameFromEnvKey( key, self.opts.envmappings) if classname: depsItem = DependencyItem(classname, methname, self.file_name, node.get('line', 0) or -1) depsItem.isCall = True # treat as if actual call, to collect recursive deps # check phase functor = node.getChild( "operand") # get the "qx.core.Environment" symbol if self.is_static_loaddep(functor): depsItem.isLoadDep = True depsItem.needsRecursion = True self.deps.append(depsItem)
def dependencies_from_envcalls(self, node): depsList = [] qcEnvClass = ClassesAll['qx.core.Environment'] 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 = qcEnvClass.classNameFromEnvKey(env_key) if className and className in ClassesAll: #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 qx_idnode = treeutil.findFirstChainChild(env_operand) # 'qx' node of 'qx.core.Environment....' scope = qx_idnode.scope depsItem.isLoadDep = scope.is_load_time if depsItem.isLoadDep: depsItem.needsRecursion = True depsList.append(depsItem) return depsList
def dependencies_from_envcalls(self, node): depsList = [] if 'qx.core.Environment' not in ClassesAll: self.context['console'].warn("No qx.core.Environment available to extract feature keys from") return depsList qcEnvClass = ClassesAll['qx.core.Environment'] for env_operand in variantoptimizer.findVariantNodes(node): call_node = env_operand.parent.parent env_key = call_node.getChild("arguments").children[0].get("value", "") # Without qx.core.Environment._checksMap: # --------------------------------------- className = qcEnvClass.classNameFromEnvKeyByIndex(env_key) if className and className in ClassesAll: #print className depsItem = DependencyItem(className, "", self.id, env_operand.get('line', -1)) depsItem.isCall = True # treat as if actual call, to collect recursive deps depsItem.node = call_node # .inLoadContext qx_idnode = treeutil.findFirstChainChild(env_operand) # 'qx' node of 'qx.core.Environment....' scope = qx_idnode.scope depsItem.isLoadDep = scope.is_load_time if depsItem.isLoadDep: depsItem.needsRecursion = True depsList.append(depsItem) # With qx.core.Environment._checksMap: # ------------------------------------ # className, classAttribute = qcEnvClass.classNameFromEnvKey(env_key) # if className and className in ClassesAll: # #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 # depsItem.node = call_node # # .inLoadContext # qx_idnode = treeutil.findFirstChainChild(env_operand) # 'qx' node of 'qx.core.Environment....' # scope = qx_idnode.scope # depsItem.isLoadDep = scope.is_load_time # if depsItem.isLoadDep: # depsItem.needsRecursion = True # depsList.append(depsItem) return depsList
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 depsItem_from_node(self, node): scope = node.scope # some initializations (might get refined later) depsItem = DependencyItem('', '', '') depsItem.name = '' depsItem.attribute = '' depsItem.requestor = self.id depsItem.line = node.get("line", -1) depsItem.isLoadDep = scope.is_load_time depsItem.needsRecursion = False depsItem.isCall = False depsItem.node = node var_root = treeutil.findVarRoot(node) # various of the tests need the var (dot) root, rather than the head symbol (like 'qx') # .isCall if treeutil.isCallOperand(var_root): # it's a function call or new op. depsItem.isCall = True # interesting when following transitive deps # .name, .attribute assembled = (treeutil.assembleVariable(node))[0] className = gs.test_for_libsymbol(assembled, ClassesAll, []) # TODO: no namespaces!? if not className: is_lib_class = False className = assembled classAttribute = '' else: is_lib_class = True if len(assembled) > len(className): classAttribute = assembled[len(className)+1:] dotidx = classAttribute.find(".") # see if classAttribute is chained too if dotidx > -1: classAttribute = classAttribute[:dotidx] # only use the first component else: classAttribute = '' # we allow self-references, to be able to track method dependencies within the same class assembled_parts = assembled.split('.') if assembled_parts[0] == 'this': className = self.id is_lib_class = True if '.' in assembled: classAttribute = assembled_parts[1] elif scope.is_defer and assembled_parts[0] in DEFER_ARGS: className = self.id is_lib_class = True if '.' in assembled: classAttribute = assembled_parts[1] if is_lib_class and not classAttribute: # see if we have to provide 'construct' if treeutil.isNEWoperand(var_root): classAttribute = 'construct' depsItem.name = className depsItem.attribute = classAttribute # .needsRecursion # Mark items that need recursive analysis of their dependencies (bug#1455) if (is_lib_class and scope.is_load_time and (treeutil.isCallOperand(var_root) or treeutil.isNEWoperand(var_root))): depsItem.needsRecursion = True return depsItem
def depsItem_from_node(self, node): scope = node.scope # some initializations (might get refined later) depsItem = DependencyItem('', '', '') depsItem.name = '' depsItem.attribute = '' depsItem.requestor = self.id depsItem.line = node.get("line", -1) depsItem.isLoadDep = scope.is_load_time depsItem.needsRecursion = False depsItem.isCall = False depsItem.node = node is_lib_class = False var_root = treeutil.findVarRoot( node ) # various of the tests need the var (dot) root, rather than the head symbol (like 'qx') # .isCall if treeutil.isCallOperand(var_root): # it's a function call or new op. depsItem.isCall = True # interesting when following transitive deps # .name, .attribute assembled = (treeutil.assembleVariable(node))[0] className, classAttribute = self._splitQxClass(assembled) assembled_parts = assembled.split('.') if not className: if "." in assembled: className = '.'.join(assembled_parts[:-1]) classAttribute = assembled_parts[-1] #className, classAttribute = assembled.split('.')[:2] else: className = assembled else: is_lib_class = True # we allow self-references, to be able to track method dependencies within the same class if assembled_parts[0] == 'this': className = self.id is_lib_class = True if '.' in assembled: classAttribute = assembled_parts[1] elif scope.is_defer and assembled_parts[0] in DEFER_ARGS: className = self.id is_lib_class = True if '.' in assembled: classAttribute = assembled_parts[1] if is_lib_class and not classAttribute: # see if we have to provide 'construct' if treeutil.isNEWoperand(var_root): classAttribute = 'construct' depsItem.name = className depsItem.attribute = classAttribute # .needsRecursion # Mark items that need recursive analysis of their dependencies (bug#1455) #if self.followCallDeps(var_root, self.id, className, isLoadTime): #if self.id=='qx.bom.element.Style' and depsItem.attribute=='__detectVendorProperties': # import pydb; pydb.debugger() if (is_lib_class and scope.is_load_time and (treeutil.isCallOperand(var_root) or treeutil.isNEWoperand(var_root))): depsItem.needsRecursion = True return depsItem