Esempio n. 1
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
                    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)
Esempio n. 3
0
    def class_declared_privates(self, class_def_node):
        try:
            class_map = treeutil.getClassMap(class_def_node)
        except tree.NodeAccessException:
            return

        for category in ('statics', 'members'):
            # collect all privates
            if category in class_map:
                private_keys = set()
                for key in class_map[category]:
                    if self.reg_privs.match(key):
                        private_keys.add(key)
                # go through uses of 'this' and 'that' that reference a private
                items = class_map[category].items()
                if category == "members" and 'construct' in class_map: # add checking constructor
                    items.insert(0, ('construct', class_map['construct'].parent  # to recover (value ...)
                        ))
                for key,val in items:
                    if val.children[0].type == 'function':
                        function_privs = self.function_uses_local_privs(val.children[0])
                        for priv, node in function_privs:
                            if priv not in private_keys:
                                issue = warn("Using an undeclared private class feature: '%s'" % priv, self.file_name, node)
                                self.issues.append(issue)
Esempio n. 4
0
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
Esempio n. 5
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)
Esempio n. 6
0
def optimize(classDefine, classDefNodes):
    patchCount = 0

    # get class map
    try:
        classMap = treeutil.getClassMap(classDefine)
    except tree.NodeAccessException:  # this might happen when the second param is not a map literal
        return 0

    if not "extend" in classMap:
        return 0

    if classMap["extend"].type == "variable":
        superClass = treeutil.assembleVariable(classMap["extend"])[0]
    else:
        return 0  # interfaces can have a list-valued "extend", but we currently don't optimize those

    if "construct" in classMap:
        patchCount = optimizeConstruct(classMap["construct"], superClass,
                                       "construct", classDefNodes)

    if not "members" in classMap:
        return patchCount

    members = classMap["members"]
    for methodName, methodNode in members.items():
        patchCount += optimizeConstruct(methodNode, superClass, methodName,
                                        classDefNodes)

    return patchCount
Esempio n. 7
0
    def class_declared_privates(self, class_def_node):
        try:
            class_map = treeutil.getClassMap(class_def_node)
        except tree.NodeAccessException:
            return

        for category in ('statics', 'members'):
            # collect all privates
            if category in class_map:
                private_keys = set()
                for key in class_map[category]:
                    if self.reg_privs.match(key):
                        private_keys.add(key)
                # go through uses of 'this' and 'that' that reference a private
                items = class_map[category].items()
                if category == "members" and 'construct' in class_map:  # add checking constructor
                    items.insert(
                        0,
                        (
                            'construct',
                            class_map['construct'].
                            parent  # to recover (value ...)
                        ))
                for key, val in items:
                    if val.children[0].type == 'function':
                        function_privs = self.function_uses_local_privs(
                            val.children[0])
                        for priv, node in function_privs:
                            if priv not in private_keys:
                                warn(
                                    "Using an undeclared private class feature: '%s'"
                                    % priv, self.file_name, node)
Esempio n. 8
0
def optimize(classDefine, classDefNodes):
    patchCount = 0

    # get class map
    try:
        classMap = treeutil.getClassMap(classDefine)
    except tree.NodeAccessException:  # this might happen when the second param is not a map literal
        return 0

    if not "extend" in classMap:
        return 0

    if classMap["extend"].type == "variable":
        superClass = treeutil.assembleVariable(classMap["extend"])[0]
    else:
        return 0  # interfaces can have a list-valued "extend", but we currently don't optimize those

    if "construct" in classMap:
        patchCount = optimizeConstruct(classMap["construct"], superClass, "construct", classDefNodes)

    if not "members" in classMap:
        return patchCount

    members = classMap["members"]
    for methodName, methodNode in members.items():
        patchCount += optimizeConstruct(methodNode, superClass, methodName, classDefNodes)

    return patchCount
Esempio n. 9
0
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
Esempio n. 10
0
    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
Esempio n. 11
0
    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
Esempio n. 12
0
 def node_is_defer_value(self, node):
     is_defer = False
     # find qxDefine in tree
     for qx_def_node in treeutil.findQxDefineR(self.root_node):
         class_map = treeutil.getClassMap(qx_def_node)
         if 'defer' in class_map and class_map['defer'] == node:
             is_defer = True
             break
     return is_defer
Esempio n. 13
0
 def node_is_defer_value(self, node):
     is_defer = False
     # find qxDefine in tree
     for qx_def_node in treeutil.findQxDefineR(self.root_node):
         class_map = treeutil.getClassMap(qx_def_node)
         if 'defer' in class_map and class_map['defer'] == node:
             is_defer = True
             break
     return is_defer
Esempio n. 14
0
 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
Esempio n. 15
0
 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
Esempio n. 16
0
        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
Esempio n. 17
0
    def class_reference_fields(self, class_def_node):
        try:
            class_map = treeutil.getClassMap(class_def_node)
        except tree.NodeAccessException:
            return
        # only check members
        members_map = class_map['members'] if 'members' in class_map else {}

        for key, val in members_map.items():
            value_node = val.children[0]
            if (value_node.type in ("map", "array") or
                (value_node.type == "operation" and value_node.get("operator")=="NEW")):
                ok = False
                at_hints = get_at_hints(value_node)
                if at_hints:
                    ok = self.is_name_lint_filtered(key, at_hints, "ignoreReferenceField")
                if not ok:
                    warn("Reference values are shared across all instances: '%s'" % key, self.file_name, value_node)
Esempio n. 18
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)
Esempio n. 19
0
    def getClassMap(self, variants):
        tree = self.tree ()
        qxDefine = treeutil.findQxDefine (tree)
        classMap = treeutil.getClassMap (qxDefine)

        return classMap