def processVariantGet(callNode, variantMap): treeModified = False # Simple sanity checks params = callNode.getChild("arguments") if len(params.children) != 1: return treeModified firstParam = params.getChildByPosition(0) if not treeutil.isStringLiteral(firstParam): 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 getSelectParams(callNode): result = (None, None) if callNode.type != "call": return result params = callNode.getChild("arguments") if len(params.children) != 2: log( "Warning", "Expecting exactly two arguments for qx.core.Environment.select. Ignoring this occurrence.", params) return result # Get the variant key from the select() call firstParam = params.getChildByPosition(0) if not treeutil.isStringLiteral(firstParam): # warning is currently covered in parsing code #log("Warning", "First argument must be a string literal constant! Ignoring this occurrence.", firstParam) return result variantKey = firstParam.get("value") # Get the resolution map, keyed by possible variant key values (or value expressions) secondParam = params.getChildByPosition(1) branchMap = {} if secondParam.type == "map": for node in secondParam.children: if node.type != "keyvalue": continue branchKey = node.get("key") value = node.getChild("value").getFirstChild() branchMap[branchKey] = value return variantKey, branchMap
def _variantsFromTree(self, node): console = self.context["console"] config = self.context["jobconf"] warn_non_literal_keys = "non-literal-keys" not in config.get("config-warnings/environment", []) classvariants = set() for variantNode in variantoptimizer.findVariantNodes(node): firstParam = treeutil.selectNode(variantNode, "../../params/1") if firstParam: if treeutil.isStringLiteral(firstParam): classvariants.add(firstParam.get("value")) elif firstParam.type == "variable": if warn_non_literal_keys: console.warn( "qx.core.Environment call with non-literal key (%s:%s)" % (self.id, variantNode.get("line", False)) ) elif firstParam.type == "map": # e.g. .filter() method mapMap = treeutil.mapNodeToMap(firstParam) classvariants.update(mapMap.keys()) else: console.warn( "qx.core.Environment call with alien first argument (%s:%s)" % (self.id, variantNode.get("line", False)) ) return classvariants
def environment_check_get(self, get_call): # Simple sanity checks params = get_call.getChild("arguments") if len(params.children) != 1: issue = warn("qx.core.Environment.get: takes exactly one argument.", self.file_name, get_call) self.issues.append(issue) return False firstParam = params.getChildByPosition(0) if not treeutil.isStringLiteral(firstParam): ok = False if self.opts.ignore_environment_nonlit_key: ok = True else: lint_key = "environmentNonLiteralKey" at_hints = get_at_hints(get_call) if at_hints: if ((lint_key in at_hints['lint'] and not len(at_hints['lint'][lint_key])) # environmentNonLiteralKey() or self.is_name_lint_filtered(firstParam.toJS(None), at_hints, lint_key)): # environmentNonLiteralKey(foo) ok = True if not ok: issue = warn("qx.core.Environment.get: first argument is not a string literal.", self.file_name, get_call) self.issues.append(issue) return False
def processVariantGet(callNode, variantMap): treeModified = False # Simple sanity checks params = callNode.getChild("arguments") if len(params.children) != 1: return treeModified firstParam = params.getChildByPosition(0) if not treeutil.isStringLiteral(firstParam): 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 environment_check_get(self, get_call): # Simple sanity checks params = get_call.getChild("arguments") if len(params.children) != 1: warn("qx.core.Environment.get: takes exactly one argument.", self.file_name, get_call) return False firstParam = params.getChildByPosition(0) if not treeutil.isStringLiteral(firstParam): ok = False if self.opts.ignore_environment_nonlit_key: ok = True else: lint_key = "environmentNonLiteralKey" at_hints = get_at_hints(get_call) if at_hints: if ((lint_key in at_hints['lint'] and not len(at_hints['lint'][lint_key]) ) # environmentNonLiteralKey() or self.is_name_lint_filtered( firstParam.toJS(None), at_hints, lint_key)): # environmentNonLiteralKey(foo) ok = True if not ok: warn( "qx.core.Environment.get: first argument is not a string literal.", self.file_name, get_call) return False
def getSelectParams(callNode): result = (None, None) if callNode.type != "call": return result params = callNode.getChild("arguments") if len(params.children) != 2: log( "Warning", "Expecting exactly two arguments for qx.core.Environment.select. Ignoring this occurrence.", params, ) return result # Get the variant key from the select() call firstParam = params.getChildByPosition(0) if not treeutil.isStringLiteral(firstParam): # warning is currently covered in parsing code # log("Warning", "First argument must be a string literal constant! Ignoring this occurrence.", firstParam) return result variantKey = firstParam.get("value") # Get the resolution map, keyed by possible variant key values (or value expressions) secondParam = params.getChildByPosition(1) branchMap = {} if secondParam.type == "map": for node in secondParam.children: if node.type != "keyvalue": continue branchKey = node.get("key") value = node.getChild("value").getFirstChild() branchMap[branchKey] = value return variantKey, branchMap
def _variantsFromTree(self, node): console = self.context['console'] #config = self.context['jobconf'] - TODO: this can yield job 'apiconf::build-resources' when running 'apiconf::build-data'!? config = Context.jobconf warn_non_literal_keys = "non-literal-keys" not in config.get( "config-warnings/environment", []) classvariants = set() for variantNode in variantoptimizer.findVariantNodes(node): firstParam = treeutil.selectNode(variantNode, "../../params/1") if firstParam: if treeutil.isStringLiteral(firstParam): classvariants.add(firstParam.get("value")) elif firstParam.isVar(): if warn_non_literal_keys: console.warn( "qx.core.Environment call with non-literal key (%s:%s)" % (self.id, variantNode.get("line", False))) elif firstParam.type == "map": # e.g. .filter() method mapMap = treeutil.mapNodeToMap(firstParam) classvariants.update(mapMap.keys()) else: console.warn( "qx.core.Environment call with alien first argument (%s:%s)" % (self.id, variantNode.get("line", False))) return classvariants
def _variantsFromTree(self, node): console = self.context['console'] classvariants = set([]) for variantNode in variantoptimizer.findVariantNodes(node): firstParam = treeutil.selectNode(variantNode, "../../params/1") if firstParam and treeutil.isStringLiteral(firstParam): classvariants.add(firstParam.get("value")) else: console.warn("qx.core.Environment call without literal argument (%s:%s)" % (self.id, variantNode.get("line", False))) return classvariants
def environment_check_select(self, select_call): if select_call.type != "call": return False params = select_call.getChild("arguments") if len(params.children) != 2: issue = warn( "qx.core.Environment.select: takes exactly two arguments.", self.file_name, select_call) self.issues.append(issue) return False # Get the variant key from the select() call firstParam = params.getChildByPosition(0) #evaluate.evaluate(firstParam) #firstValue = firstParam.evaluated #if firstValue == () or not isinstance(firstValue, types.StringTypes): if not treeutil.isStringLiteral(firstParam): ok = False if self.opts.ignore_environment_nonlit_key: ok = True else: lint_key = "environmentNonLiteralKey" at_hints = get_at_hints(select_call) if at_hints: if ((lint_key in at_hints['lint'] and not len(at_hints['lint'][lint_key]) ) # environmentNonLiteralKey() or self.is_name_lint_filtered( firstParam.toJS(None), at_hints, lint_key)): # environmentNonLiteralKey(foo) ok = True if not ok: issue = warn( "qx.core.Environment.select: first argument is not a string literal.", self.file_name, select_call) self.issues.append(issue) return False # Get the resolution map, keyed by possible variant key values (or value expressions) secondParam = params.getChildByPosition(1) default = None found = False if secondParam.type == "map": # we could try to check a relevant key from a variantsMap against the possibilities in the code # like in variantoptimzier - deferred pass else: issue = warn( "qx.core.Environment.select: second parameter is not a map.", self.file_name, select_call) self.issues.append(issue)
def _variantsFromTree(self, node): console = self.context['console'] classvariants = set() for variantNode in variantoptimizer.findVariantNodes(node): firstParam = treeutil.selectNode(variantNode, "../../params/1") if firstParam: if treeutil.isStringLiteral(firstParam): classvariants.add(firstParam.get("value")) elif firstParam.type == "map": # e.g. .filter() method mapMap = treeutil.mapNodeToMap(firstParam) classvariants.update(mapMap.keys()) else: console.warn("qx.core.Environment call with alien first argument (%s:%s)" % (self.id, variantNode.get("line", False))) return classvariants
def getClassVariantsFromTree(node, console): classvariants = set([]) # mostly taken from ecmascript.transform.optimizer.variantoptimizer variants = treeutil.findVariablePrefix(node, "qx.core.Variant") for variant in variants: if not variant.hasParentContext("call/operand"): continue variantMethod = treeutil.selectNode(variant, "identifier[4]/@name") if variantMethod not in ["select", "isSet", "compilerIsSet"]: continue firstParam = treeutil.selectNode(variant, "../../params/1") if firstParam and treeutil.isStringLiteral(firstParam): classvariants.add(firstParam.get("value")) else: console.warn("! qx.core.Variant call without literal argument") return classvariants
def environment_check_select(self, select_call): if select_call.type != "call": return False params = select_call.getChild("arguments") if len(params.children) != 2: issue = warn("qx.core.Environment.select: takes exactly two arguments.", self.file_name, select_call) self.issues.append(issue) return False # Get the variant key from the select() call firstParam = params.getChildByPosition(0) #evaluate.evaluate(firstParam) #firstValue = firstParam.evaluated #if firstValue == () or not isinstance(firstValue, types.StringTypes): if not treeutil.isStringLiteral(firstParam): ok = False if self.opts.ignore_environment_nonlit_key: ok = True else: lint_key = "environmentNonLiteralKey" at_hints = get_at_hints(select_call) if at_hints: if ((lint_key in at_hints['lint'] and not len(at_hints['lint'][lint_key])) # environmentNonLiteralKey() or self.is_name_lint_filtered(firstParam.toJS(None), at_hints, lint_key)): # environmentNonLiteralKey(foo) ok = True if not ok: issue = warn("qx.core.Environment.select: first argument is not a string literal.", self.file_name, select_call) self.issues.append(issue) return False # Get the resolution map, keyed by possible variant key values (or value expressions) secondParam = params.getChildByPosition(1) default = None found = False if secondParam.type == "map": # we could try to check a relevant key from a variantsMap against the possibilities in the code # like in variantoptimzier - deferred pass else: issue = warn("qx.core.Environment.select: second parameter is not a map.", self.file_name, select_call) self.issues.append(issue)
def _variantsFromTree(self, node): console = self.context['console'] #config = self.context['jobconf'] - TODO: this can yield job 'apiconf::build-resources' when running 'apiconf::build-data'!? config = Context.jobconf warn_non_literal_keys = "non-literal-keys" not in config.get("config-warnings/environment",[]) classvariants = set() for variantNode in variantoptimizer.findVariantNodes(node): firstParam = treeutil.selectNode(variantNode, "../../params/1") if firstParam: if treeutil.isStringLiteral(firstParam): classvariants.add(firstParam.get("value")) elif firstParam.isVar(): if warn_non_literal_keys: console.warn("qx.core.Environment call with non-literal key (%s:%s)" % (self.id, variantNode.get("line", False))) elif firstParam.type == "map": # e.g. .filter() method mapMap = treeutil.mapNodeToMap(firstParam) classvariants.update(mapMap.keys()) else: console.warn("qx.core.Environment call with alien first argument (%s:%s)" % (self.id, variantNode.get("line", False))) return classvariants
def processVariantGet(callNode, variantMap): treeModified = False # Simple sanity checks params = callNode.getChild("arguments") if len(params.children) != 1: return treeModified firstParam = params.getChildByPosition(0) if not treeutil.isStringLiteral(firstParam): 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 return treeModified
def processVariantGet(callNode, variantMap): treeModified = False # Simple sanity checks params = callNode.getChild("arguments") if len(params.children) != 1: return treeModified firstParam = params.getChildByPosition(0) if not treeutil.isStringLiteral(firstParam): 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 return treeModified
def processVariantSelect(callNode, variantMap): if callNode.type != "call": return False params = callNode.getChild("arguments") if len(params.children) != 2: log( "Warning", "Expecting exactly two arguments for qx.core.Environment.select. Ignoring this occurrence.", params, ) return False # Get the variant key from the select() call firstParam = params.getChildByPosition(0) if not treeutil.isStringLiteral(firstParam): # warning is currently covered in parsing code # log("Warning", "First argument must be a string literal constant! Ignoring this occurrence.", firstParam) return False variantKey = firstParam.get("value") # is this key covered by the current variant map? if variantKey in variantMap: variantValue = variantMap[variantKey] else: return False # Get the resolution map, keyed by possible variant key values (or value expressions) secondParam = params.getChildByPosition(1) default = None found = False if secondParam.type == "map": # map keys are always JS strings -> simulate a JS .toString() conversion if isinstance(variantValue, types.BooleanType): # this has to come first, as isinstance(True, types.IntType) is also true! variantValue = str(variantValue).lower() elif isinstance(variantValue, (types.IntType, types.FloatType)): variantValue = str(variantValue) elif variantValue == None: variantValue = "null" for node in secondParam.children: if node.type != "keyvalue": continue mapkey = node.get("key") mapvalue = node.getChild("value").getFirstChild() keys = mapkey.split("|") # Go through individual key constants for key in keys: if key == variantValue: callNode.parent.replaceChild(callNode, mapvalue) found = True break if key == "default": default = mapvalue if not found: if default != None: callNode.parent.replaceChild(callNode, default) else: raise RuntimeError( makeLogMessage( "Error", "Variantoptimizer: No matching case found for variant (%s:%s) at" % (variantKey, variantValue), callNode, ) ) return True log( "Warning", "The second parameter of qx.core.Environment.select must be a map or a string literal. Ignoring this occurrence.", secondParam, ) return False
def processVariantSelect(callNode, variantMap): if callNode.type != "call": return False params = callNode.getChild("arguments") if len(params.children) != 2: log( "Warning", "Expecting exactly two arguments for qx.core.Environment.select. Ignoring this occurrence.", params) return False # Get the variant key from the select() call firstParam = params.getChildByPosition(0) if not treeutil.isStringLiteral(firstParam): # warning is currently covered in parsing code #log("Warning", "First argument must be a string literal constant! Ignoring this occurrence.", firstParam) return False variantKey = firstParam.get("value") # is this key covered by the current variant map? if variantKey in variantMap: variantValue = variantMap[variantKey] else: return False # Get the resolution map, keyed by possible variant key values (or value expressions) secondParam = params.getChildByPosition(1) default = None found = False if secondParam.type == "map": # map keys are always JS strings -> simulate a JS .toString() conversion if isinstance(variantValue, types.BooleanType): # this has to come first, as isinstance(True, types.IntType) is also true! variantValue = str(variantValue).lower() elif isinstance(variantValue, (types.IntType, types.FloatType)): variantValue = str(variantValue) elif variantValue == None: variantValue = "null" for node in secondParam.children: if node.type != "keyvalue": continue mapkey = node.get("key") mapvalue = node.getChild("value").getFirstChild() keys = mapkey.split("|") # Go through individual key constants for key in keys: if (key == variantValue): callNode.parent.replaceChild(callNode, mapvalue) found = True break if key == "default": default = mapvalue if not found: if default != None: callNode.parent.replaceChild(callNode, default) else: raise RuntimeError( makeLogMessage( "Error", "Variantoptimizer: No matching case found for variant (%s:%s) at" % (variantKey, variantValue), callNode)) return True log( "Warning", "The second parameter of qx.core.Environment.select must be a map or a string literal. Ignoring this occurrence.", secondParam) return False