def checkNodeContext(node): context = 'interesting' # every context is interesting, mybe we get more specific #context = '' # filter out the occurrences like 'c' in a.b().c myFirst = node.getFirstChild(mandatory=False, ignoreComments=True) if not treeutil.checkFirstChainChild(myFirst): # see if myFirst is the first identifier in a chain context = '' # filter out variable in lval position -- Nope! (qx.ui.form.ListItem.prototype.setValue = # function(..){...};) #elif (node.hasParentContext("assignment/left")): # context = '' # fitler out a.b[c] -- Nope! E.g. foo.ISO_8601_FORMAT might carry further dependencies # (like 'new qx.util.format.DateFormat("yyyy-MM-dd")') elif (treeutil.selectNode(node, "accessor")): context = 'accessor' # check name in 'new ...' position elif (node.hasParentContext("instantiation/*/*/operand")): context = 'new' # check name in call position elif (node.hasParentContext("call/operand")): context = 'call' # check name in "'extend' : ..." position elif (node.hasParentContext("keyvalue/*") and node.parent.parent.get('key') in ['extend']): #, 'include']): #print "-- found context: %s" % node.parent.parent.get('key') context = 'extend' return context
def checkNodeContext(node): context = 'interesting' # every context is interesting, mybe we get more specific #context = '' # filter out the occurrences like 'c' in a.b().c myFirst = node.getFirstChild(mandatory=False, ignoreComments=True) if not treeutil.checkFirstChainChild(myFirst): # see if myFirst is the first identifier in a chain context = '' # filter out ... = position (lvals) - Nope! (qx.ui.form.ListItem.prototype.setValue = # function(..){...};) #elif (node.hasParentContext("assignment/left")): # context = '' # check name in 'new ...' position elif (node.hasParentContext("instantiation/*/*/operand")): context = 'new' # check name in call position elif (node.hasParentContext("call/operand")): context = 'call' # check name in "'extend' : ..." position elif (node.hasParentContext("keyvalue/*") and node.parent.parent.get('key') in ['extend']): #, 'include']): #print "-- found context: %s" % node.parent.parent.get('key') context = 'extend' return context
def visit_identifier(self, node): # only treat leftmost identifier (e.g. in a dotaccessor expression) if treeutil.checkFirstChainChild(node): var_name = node.get('value') # lookup var var_scope = self.curr_scope.lookup_decl(var_name) if not var_scope: # it's a global reference self.curr_scope.add_use(var_name, node) node.scope = self.curr_scope else: # it's a scoped variable var_scope.add_use(var_name, node) node.scope = var_scope
def usedVariablesIterator(node): # Switch on node context: # "function", "catch": if node.type in ["function", "catch"]: return # "catch": skip the identifier of catch clauses, e.g. the 'e' in 'catch(e)' # (it belongs to the catch scope) if node.parent and node.parent.type == "catch" and node == node.parent.children[0]: return # "for-in": treat variables used in for-in loops as used variables (why?) # (undeclared variables are handled by the normal "identifier" rule # further down) if ( node.type == "var" and node.parent.type == "operation" and node.parent.get("operator") == "IN" ): use = node.getChild("definition").getDefinee() if use: name = use.get("value", False) name = None if name == False else name yield (name, use) return # "identifier": if node.type == "identifier": isFirstChild = False isVariableMember = False if node.parent.isVar(): # (the old code added "accessor" for the types to check) isVariableMember = True isFirstChild = treeutil.checkFirstChainChild(node) # inside a variable only respect the first member if not isVariableMember or isFirstChild: name = node.get("value", False) name = None if name == False else name if name: yield (name, node) # -- Recurse over children if node.children: for child in node.children: for (name, use) in Scope.usedVariablesIterator(child): yield (name, use) return
def visit_identifier(self, node): # var reference #print "var use visitor", node if treeutil.checkFirstChainChild(node): # only treat leftmost identifier (e.g. in a dotaccessor expression) var_name = node.get('value') # lookup var #if var_name == "Stack": # import pydb; pydb.debugger() var_scope = self.curr_scope.lookup_decl(var_name) if not var_scope: # it's a global reference self.curr_scope.add_use(var_name, node) node.scope = self.curr_scope else: # it's a scoped variable var_scope.add_use(var_name, node) node.scope = var_scope
def usedVariablesIterator(node): # Switch on node context: # "function", "catch": if node.type in ["function", "catch"]: return # "catch": skip the identifier of catch clauses, e.g. the 'e' in 'catch(e)' # (it belongs to the catch scope) if node.parent and node.parent.type == "catch" and node == node.parent.children[ 0]: return # "for-in": treat variables used in for-in loops as used variables (why?) # (undeclared variables are handled by the normal "identifier" rule # further down) if (node.type == "var" and node.parent.type == "operation" and node.parent.get("operator") == "IN"): use = node.getChild("definition").getDefinee() if use: name = use.get("value", False) name = None if name == False else name yield (name, use) return # "identifier": if node.type == "identifier": isFirstChild = False isVariableMember = False if node.parent.isVar( ): # (the old code added "accessor" for the types to check) isVariableMember = True isFirstChild = treeutil.checkFirstChainChild(node) # inside a variable only respect the first member if not isVariableMember or isFirstChild: name = node.get("value", False) name = None if name == False else name if name: yield (name, node) # -- Recurse over children if node.children: for child in node.children: for (name, use) in Scope.usedVariablesIterator(child): yield (name, use) return
def processVariantGet(callNode, variantMap): treeModified = False # Simple sanity checks params = callNode.getChild("params") if len(params.children) != 1: log( "Warning", "Expecting exactly one argument for qx.core.Environment.get. Ignoring this occurrence.", params) return treeModified firstParam = params.getChildByPosition(0) if not isStringLiteral(firstParam): # warning is currently covered in parsing code #log("Warning", "First argument must be a string literal! Ignoring this occurrence.", firstParam) return treeModified # skipping "relative" calls like "a.b.qx.core.Environment.get()" qxIdentifier = treeutil.selectNode(callNode, "operand/variable/identifier[1]") if not treeutil.checkFirstChainChild(qxIdentifier): log( "Warning", "Skipping relative qx.core.Environment.get call. Ignoring this occurrence ('%s')." % treeutil.findChainRoot(qxIdentifier).toJavascript()) return treeModified variantKey = firstParam.get("value") if variantKey in variantMap: confValue = variantMap[variantKey] else: return treeModified # Replace the .get() with its value resultNode = reduceCall(callNode, confValue) treeModified = True # Reduce any potential operations with literals (+3, =='hugo', ?a:b, ...) treeMod = True while treeMod: resultNode, treeMod = reduceOperation(resultNode) # Reduce a potential condition _ = reduceLoop(resultNode) return treeModified
def visit_identifier(self, node): # var reference #print "var use visitor", node if treeutil.checkFirstChainChild( node ): # only treat leftmost identifier (e.g. in a dotaccessor expression) var_name = node.get('value') # lookup var #if var_name == "Stack": # import pydb; pydb.debugger() var_scope = self.curr_scope.lookup_decl(var_name) if not var_scope: # it's a global reference self.curr_scope.add_use(var_name, node) node.scope = self.curr_scope else: # it's a scoped variable var_scope.add_use(var_name, node) node.scope = var_scope
def processVariantGet(callNode, variantMap): treeModified = False # Simple sanity checks params = callNode.getChild("params") if len(params.children) != 1: log("Warning", "Expecting exactly one argument for qx.core.Environment.get. Ignoring this occurrence.", params) return treeModified firstParam = params.getChildByPosition(0) if not isStringLiteral(firstParam): log("Warning", "First argument must be a string literal! Ignoring this occurrence.", firstParam) return treeModified # skipping "relative" calls like "a.b.qx.core.Environment.get()" qxIdentifier = treeutil.selectNode(callNode, "operand/variable/identifier[1]") if not treeutil.checkFirstChainChild(qxIdentifier): log( "Warning", "Skipping relative qx.core.Environment.get call. Ignoring this occurrence ('%s')." % treeutil.findChainRoot(qxIdentifier).toJavascript(), ) return treeModified variantKey = firstParam.get("value") if variantKey in variantMap: confValue = variantMap[variantKey] else: return treeModified # Replace the .get() with its value resultNode = reduceCall(callNode, confValue) treeModified = True # Reduce any potential operations with literals (+3, =='hugo', ?a:b, ...) treeMod = True while treeMod: resultNode, treeMod = reduceOperation(resultNode) # Reduce a potential condition _ = reduceLoop(resultNode) return treeModified