def patch(tree, id): define = treeutil.findQxDefine(tree) if define == None: return mainChildren = define.getChild("arguments").children if len(mainChildren) <= 1: return mainBlock = mainChildren[1].children properties = None members = None for entry in mainBlock: key = entry.get("key") if key == "properties": properties = entry.getChild("value").getFirstChild() if key == "members": members = entry.getChild("value").getFirstChild() if properties and members: transfer(id, properties, members)
def patch(tree, id, feature_names): # get class map qxDefine = treeutil.findQxDefine(tree) classMap = treeutil.getClassMap(qxDefine) # go through features in 'members' and 'statics' for section in ("statics", "members"): if section in classMap: for key, node in classMap[section].items(): # skip registered keys if key in feature_names: continue # skip non-function attribs meth = None if node.type == 'function': meth = node else: meth = treeutil.selectNode(node, "function") if not meth: continue # prune else: parent = node.parent assert parent.type == "keyvalue" #print "pruning: %s#%s" % (id, key) parent.parent.removeChild( parent) # remove the entire key from the map
def checkUndefinedVariables(self, globals): # check whether this is a qooxdoo class and extract the top level namespace define = treeutil.findQxDefine(self.tree) if define: className = treeutil.selectNode(define, "params/1").get("value") globals.append(className.split(".")[0]) globalScope = self.script.getGlobalScope() for scope in self.script.iterScopes(): for use in scope.uses: if use.name in globals: continue if not use.definition: if self.isBadGlobal(use.name) and self._shouldPrintDeprecatedWarning(use.node, use.name): self.log(use.node, "Use of deprecated global identifier '%s'" % use.name) elif ( not self.isBadGlobal(use.name) and not self.isGoodGlobal(use.name) and self._shouldPrintUndefinedWarning(use.node, use.name) ): self.log(use.node, "Use of undefined or global identifier '%s'" % use.name) elif use.definition.scope == globalScope and self._shouldPrintUndefinedWarning(use.node, use.name): self.log(use.node, "Use of global identifier '%s'" % use.name)
def patch(tree, id): define = treeutil.findQxDefine(tree) if define == None: return mainChildren = define.getChild("params").children if len(mainChildren) <= 1: return mainBlock = mainChildren[1].children properties = None members = None for entry in mainBlock: key = entry.get("key") if key == "properties": properties = entry.getChild("value").getFirstChild() if key == "members": members = entry.getChild("value").getFirstChild() if properties and members: transfer(id, properties, members)
def patch(tree, classObj, featureMap): feature_names = featureMap[classObj.id] # get class map qxDefine = treeutil.findQxDefine(tree) classMap = treeutil.getClassMap(qxDefine) # go through features in 'members' and 'statics' for section in ("statics", "members"): if section in classMap: for feature, node in classMap[section].items(): # skip registered and used keys if feature in feature_names and feature_names[feature].hasref(): continue else: parent = node.parent assert parent.type == "keyvalue" #print "pruning: %s#%s" % (classObj.id, feature) parent.parent.removeChild(parent) # remove the entire feature from the map # remove from featureMap if feature in feature_names: del featureMap[classObj.id][feature] # decrease the ref counts of the contained dependees deps = [] classObj._analyzeClassDepsNode(node, deps, inLoadContext=False) # TODO: this is expensive (re-calculating deps)! # and it doesn't honor #ignores, so might decrease ref count of ignored # items! (which could lead to inconsistencies) # also, i'm calling a protected method outside the class hierarchy. for depItem in deps: if depItem.name in featureMap and depItem.attribute in featureMap[depItem.name]: depFeature = featureMap[depItem.name][depItem.attribute] depFeature.decref() # decrease reference count
def patch(tree, classObj, featureMap): # change this to 'False' if you want logging instead of function removal prune_dont_log = True feature_names = featureMap[classObj.id] # get class map qxDefine = treeutil.findQxDefine(tree) classMap = treeutil.getClassMap(qxDefine) # go through features in 'members' and 'statics' for section in ("statics", "members"): if section in classMap: for feature, node in classMap[section].items(): # skip registered and used keys if feature in feature_names and feature_names[feature].hasref(): continue else: parent = node.parent assert parent.type == "keyvalue" #print "static optimizing: %s#%s" % (classObj.id, feature) if prune_dont_log: # remove sub tree parent.parent.removeChild(parent) # remove the entire feature from the map # remove from featureMap if feature in feature_names: del featureMap[classObj.id][feature] # decrease the ref counts of the contained dependees decrementFromCode(classObj, node, featureMap) else: # OR: only add runtime logging to functions block = treeutil.selectNode(node, 'function/body/block/statements') if block: LogStmt = treegenerator.parse("console.warn('Static optimization would have removed: " + classObj.id + '#' + feature + "');") block.addChild(LogStmt, 0)
def patch(tree, classObj, featureMap): feature_names = featureMap[classObj.id] # get class map qxDefine = treeutil.findQxDefine(tree) classMap = treeutil.getClassMap(qxDefine) # go through features in 'members' and 'statics' for section in ("statics", "members"): if section in classMap: for feature, node in classMap[section].items(): # skip registered and used keys if feature in feature_names and feature_names[feature].hasref( ): continue else: parent = node.parent assert parent.type == "keyvalue" #print "pruning: %s#%s" % (classObj.id, feature) parent.parent.removeChild( parent) # remove the entire feature from the map # remove from featureMap if feature in feature_names: del featureMap[classObj.id][feature] # decrease the ref counts of the contained dependees decrementFromCode(classObj, node, featureMap)
def patch(tree, id, feature_names): # get class map qxDefine = treeutil.findQxDefine(tree) classMap = treeutil.getClassMap(qxDefine) # go through features in 'members' and 'statics' for section in ("statics", "members"): if section in classMap: for key, node in classMap[section].items(): # skip registered keys if key in feature_names: continue # skip non-function attribs meth = None if node.type == 'function': meth = node else: meth = treeutil.selectNode(node, "function") if not meth: continue # prune else: parent = node.parent assert parent.type == "keyvalue" #print "pruning: %s#%s" % (id, key) parent.parent.removeChild(parent) # remove the entire key from the map
def getClassMap(self, variants): tree = self.optimize( None, ["variants"], variants ) # TODO: this might incur an extra cached tree, if not(variants) qxDefine = treeutil.findQxDefine(tree) classMap = treeutil.getClassMap(qxDefine) return classMap
def patch(tree): qxnode = treeutil.findQxDefine(tree) processBlock( treeutil.selectNode(qxnode, "params/map/keyvalue[@key='statics']/value/map")) processBlock( treeutil.selectNode(qxnode, "params/map/keyvalue[@key='members']/value/map"))
def _getClassMap(self): define = treeutil.findQxDefine(self.tree) if not define: return {} classMapNode = treeutil.selectNode(define, "params/2") if classMapNode is None: return {} classMap = treeutil.mapNodeToMap(classMapNode) return classMap
def _getCodeId(self, clazz): tree = clazz.tree() qxDefine = treeutil.findQxDefine(tree) className = treeutil.getClassName(qxDefine) illegal = self._illegalIdentifierExpr.search(className) if illegal: raise ValueError, "Item name '%s' contains illegal character '%s'" % (className, illegal.group(0)) # print "found", className return className
def _getCodeId(self, clazz): tree = clazz.tree() qxDefine = treeutil.findQxDefine(tree) className = treeutil.getClassName(qxDefine) illegal = self._illegalIdentifierExpr.search(className) if illegal: raise ValueError, "Item name '%s' contains illegal character '%s'" % ( className, illegal.group(0)) #print "found", className return className
def _getType(self): if hasattr(self, "_type"): return self._type ast = self.tree() qxDefine = treeutil.findQxDefine(ast) classMap = treeutil.getClassMap(qxDefine) if 'type' in classMap: self._type = classMap['type'].get('value') elif 'extend' not in classMap: self._type = "static" # this is qx.Class.define semantics! else: self._type = "normal" return self._type
def checkFields(self): define = treeutil.findQxDefine(self.tree) if not define: return classMapNode = treeutil.selectNode(define, "params/2") if classMapNode is None: return classMap = treeutil.mapNodeToMap(classMapNode) if not classMap.has_key("members"): return members = treeutil.mapNodeToMap(classMap["members"].children[0]) restricted = [key for key in members if key.startswith("_")] assignNodes = [ node for node in nodeIterator(classMap["members"], "assignment") ] if classMap.has_key("construct"): for node in nodeIterator(classMap["construct"], "assignment"): assignNodes.append(node) for node in assignNodes: this = treeutil.selectNode(node, "left/variable/identifier[1]/@name") if this != "this": continue field = treeutil.selectNode(node, "left/variable/identifier[2]/@name") if field is None: continue if field[0] != "_": continue elif field[1] == "_": prot = "private" else: prot = "protected" if prot == "protected": self.log( node, "Protected data field '%s'. Protected fields are deprecated. Better use private fileds in combination with getter and setter methods." % field) elif not field in restricted: self.log( node, "Implicit declaration of %s field '%s'. You should list this field in the members section." % (prot, field))
def _getCodeId(self, clazz): className = None # not-found return value tree = clazz.tree() qxDefine = treeutil.findQxDefine (tree) if qxDefine: className = treeutil.getClassName (qxDefine) if not className: # might be u'' className = None else: illegal = self._illegalIdentifierExpr.search(className) if illegal: raise ValueError, "Item name '%s' contains illegal character '%s'" % (className,illegal.group(0)) return className
def findClassForMethod(clazzId, methodId, variants): def classHasOwnMethod(classAttribs, methId): candidates = {} candidates.update(classAttribs.get("members",{})) candidates.update(classAttribs.get("statics",{})) if "construct" in classAttribs: candidates.update(dict((("construct", classAttribs.get("construct")),))) if methId in candidates.keys(): return candidates[methId] # return the definition of the attribute else: return None # get the method name if methodId == u'': # corner case: the class is being called methodId = "construct" elif methodId == "getInstance": # corner case: singletons get this from qx.Class clazzId = "qx.Class" # TODO: getter/setter are also not statically available! # handle .call() ?! if clazzId in lang.BUILTIN: # these are automatically fullfilled, signal this return True, True elif clazzId not in self._classesObj: # can't further process non-qooxdoo classes return None, None tree = self._classesObj[clazzId].tree( variants) clazz = treeutil.findQxDefine(tree) classAttribs = treeutil.getClassMap(clazz) keyval = classHasOwnMethod(classAttribs, methodId) if keyval: return clazzId, keyval # inspect inheritance/mixins parents = [] extendVal = classAttribs.get('extend', None) if extendVal: extendVal = treeutil.variableOrArrayNodeToArray(extendVal) parents.extend(extendVal) includeVal = classAttribs.get('include', None) if includeVal: includeVal = treeutil.variableOrArrayNodeToArray(includeVal) parents.extend(includeVal) # go through all ancestors for parClass in parents: rclass, keyval = findClassForMethod(parClass, methodId, variants) if rclass: return rclass, keyval return None, None
def _getCodeId(self, clazz): className = None # not-found return value tree = clazz.tree() qxDefine = treeutil.findQxDefine(tree) if qxDefine: className = treeutil.getClassName(qxDefine) if not className: # might be u'' className = None else: illegal = self._illegalIdentifierExpr.search(className) if illegal: raise ValueError, "Item name '%s' contains illegal character '%s'" % ( className, illegal.group(0)) return className
def checkFields(self): define = treeutil.findQxDefine(self.tree) if not define: return classMapNode = treeutil.selectNode(define, "params/2") if classMapNode is None: return classMap = treeutil.mapNodeToMap(classMapNode) if not classMap.has_key("members"): return members = treeutil.mapNodeToMap(classMap["members"].children[0]) restricted = [key for key in members if key.startswith("_")] assignNodes = [node for node in treeutil.nodeIterator(classMap["members"], "assignment")] if classMap.has_key("construct"): for node in treeutil.nodeIterator(classMap["construct"], "assignment"): assignNodes.append(node) for node in assignNodes: this = treeutil.selectNode(node, "left/variable/identifier[1]/@name") if this != "this": continue field = treeutil.selectNode(node, "left/variable/identifier[2]/@name") if field is None: continue if field[0] != "_": continue elif field[1] == "_": prot = "private" else: prot = "protected" if prot == "protected": self.log(node, "Protected data field '%s'. Protected fields are deprecated. Better use private fields in combination with getter and setter methods." % field) elif not field in restricted: self.log(node, "Implicit declaration of %s field '%s'. You should list this field in the members section." % (prot, field))
def checkClassId(self, tree): className = None # not-found return value filePathId = self.id qxDefine = treeutil.findQxDefine(tree) if qxDefine: className = treeutil.getClassName(qxDefine) if not className: # might be u'' className = None else: illegal = self._illegalIdentifierExpr.search(className) if illegal: raise ValueError, "Item name '%s' contains illegal character '%s'" % (className,illegal.group(0)) if className and className != filePathId: errmsg = [ u"Detected conflict between filename and classname!\n", u" Classname: %s\n" % className, u" Path: %s\n" % filePathId, ] raise RuntimeError(u''.join(errmsg)) return
def patch(tree, classObj, featureMap): feature_names = featureMap[classObj.id] # get class map qxDefine = treeutil.findQxDefine(tree) classMap = treeutil.getClassMap(qxDefine) # go through features in 'members' and 'statics' for section in ("statics", "members"): if section in classMap: for feature, node in classMap[section].items(): # skip registered and used keys if feature in feature_names and feature_names[feature].hasref(): continue else: parent = node.parent assert parent.type == "keyvalue" #print "pruning: %s#%s" % (classObj.id, feature) parent.parent.removeChild(parent) # remove the entire feature from the map # remove from featureMap if feature in feature_names: del featureMap[classObj.id][feature] # decrease the ref counts of the contained dependees decrementFromCode(classObj, node, featureMap)
def checkUndefinedVariables(self, globals): # check whether this is a qooxdoo class and extract the top level namespace define = treeutil.findQxDefine(self.tree) if define: className = treeutil.selectNode(define, "params/1").get("value") globals.append(className.split(".")[0]) globalScope = self.script.getGlobalScope() for scope in self.script.iterScopes(): for use in scope.uses: if use.name in globals: continue if not use.definition: if self.isBadGlobal( use.name) and self._shouldPrintDeprecatedWarning( use.node, use.name): self.log( use.node, "Use of deprecated global identifier '%s'" % use.name) elif not self.isBadGlobal( use.name) and not self.isGoodGlobal( use.name ) and self._shouldPrintUndefinedWarning( use.node, use.name): self.log( use.node, "Use of undefined or global identifier '%s'" % use.name) elif use.definition.scope == globalScope and self._shouldPrintUndefinedWarning( use.node, use.name): self.log(use.node, "Use of global identifier '%s'" % use.name)
def getClassMap(self, variants): tree = self.tree () qxDefine = treeutil.findQxDefine (tree) classMap = treeutil.getClassMap (qxDefine) return classMap
def patch(tree): qxnode = treeutil.findQxDefine(tree) processBlock(treeutil.selectNode(qxnode, "arguments/map/keyvalue[@key='statics']/value/map")) processBlock(treeutil.selectNode(qxnode, "arguments/map/keyvalue[@key='members']/value/map"))