Exemple #1
0
def optimizeConstruct(node, superClass, methodName, classDefNodes):
    patchCount = 0

    # Need to run through all the nodes, to skip embedded qx.*.define(),
    # which will be treated separately

    # Handle Node

    # skip embedded qx.*.define()
    if node in classDefNodes:
        return 0

    elif node.type == "variable" and node.hasParentContext("call/operand"):

        varName, complete = treeutil.assembleVariable(node)
        if not (complete and varName == "this.base"):
            return 0

        call = node.parent.parent

        try:
            firstArgName = treeutil.selectNode(call,
                                               "params/1/identifier/@name")
        except tree.NodeAccessException:
            return 0

        if firstArgName != "arguments":
            return 0

        # "construct"
        if methodName == "construct":
            newCall = treeutil.compileString("%s.call()" % superClass)
        # "member"
        else:
            newCall = treeutil.compileString("%s.prototype.%s.call()" %
                                             (superClass, methodName))
        newCall.replaceChild(
            newCall.getChild("params"),
            call.getChild("params"))  # replace with old arglist
        treeutil.selectNode(newCall, "params/1/identifier").set(
            "name", "this")  # arguments -> this
        call.parent.replaceChild(call, newCall)
        patchCount += 1

    # Handle Children
    if node.hasChildren():
        for child in node.children:
            patchCount += optimizeConstruct(child, superClass, methodName,
                                            classDefNodes)

    return patchCount
Exemple #2
0
    def _stringOptimizer(self, tree):
        # string optimization works over a list of statements,
        # so extract the <file>'s <statements> node
        statementsNode = tree.getChild("statements")
        stringMap = stringoptimizer.search(statementsNode)

        if len(stringMap) == 0:
            return tree

        stringList = stringoptimizer.sort(stringMap)
        stringoptimizer.replace(statementsNode, stringList)

        # TODO: Re-write this using treeutil.ensureClosureWrapper()
        # Build JS string fragments
        stringStart = "(function(){"
        stringReplacement = stringoptimizer.replacement(stringList)
        stringStop = "})();"

        # Compile wrapper node
        wrapperNode = treeutil.compileString(stringStart+stringReplacement+stringStop, self.id + "||stringopt")

        # Reorganize structure
        funcStatements = (wrapperNode.getChild("operand").getChild("group").getChild("function")
                    .getChild("body").getChild("block").getChild("statements"))
        if statementsNode.hasChildren():
            for child in statementsNode.children[:]:
                statementsNode.removeChild(child)
                funcStatements.addChild(child)

        # Add wrapper to now empty statements node
        statementsNode.addChild(wrapperNode)

        return tree
Exemple #3
0
    def _stringOptimizer(self, tree):
        # string optimization works over a list of statements,
        # so extract the <file>'s <statements> node
        statementsNode = tree.getChild("statements")
        stringMap = stringoptimizer.search(statementsNode)

        if len(stringMap) == 0:
            return tree

        stringList = stringoptimizer.sort(stringMap)
        stringoptimizer.replace(statementsNode, stringList)

        # Build JS string fragments
        stringStart = "(function(){"
        stringReplacement = stringoptimizer.replacement(stringList)
        stringStop = "})();"

        # Compile wrapper node
        wrapperNode = treeutil.compileString(
            stringStart + stringReplacement + stringStop,
            self.id + "||stringopt")

        # Reorganize structure
        funcStatements = (wrapperNode.getChild("operand").getChild(
            "group").getChild("function").getChild("body").getChild(
                "block").getChild("statements"))
        if statementsNode.hasChildren():
            for child in statementsNode.children[:]:
                statementsNode.removeChild(child)
                funcStatements.addChild(child)

        # Add wrapper to now empty statements node
        statementsNode.addChild(wrapperNode)

        return tree
Exemple #4
0
def replace(node, stringList, var="$", verbose=False):
    if node.type == "constant" and node.get("constantType") == "string":
        if node.get("detail") == "singlequotes":
            quote = "'"
        elif node.get("detail") == "doublequotes":
            quote = '"'
        oldvalue = "%s%s%s" % (quote, node.get("value"), quote)

        for pos, item in enumerate(stringList):
            if item["value"] == oldvalue:
                newvalue = "%s[%s]" % (
                    var, pos)  # this is only for output, and is bogus

                if verbose:
                    poldvalue = oldvalue
                    if isinstance(poldvalue, unicode):
                        poldvalue = poldvalue.encode("utf-8")
                    print "    - Replace: %s => %s" % (poldvalue, newvalue)

                line = node.get("line")

                # generate identifier
                replacement_ident = treeutil.compileString("SSSS_%s" % pos)
                replacement_ident.set("line", node.get("line"))
                replacement_ident.set("column", node.get("column"))

                # replace node
                node.parent.replaceChild(node, replacement_ident)
                break

    if check(node, verbose):
        for child in node.children:
            replace(child, stringList, var, verbose)
    def _stringOptimizeHelper(self, tree, id, variants):
        stringMap = stringoptimizer.search(tree)

        if len(stringMap) == 0:
            return

        stringList = stringoptimizer.sort(stringMap)
        stringoptimizer.replace(tree, stringList)

        # Build JS string fragments
        stringStart = "(function(){"
        stringReplacement = stringoptimizer.replacement(stringList)
        stringStop = "})();"

        # Compile wrapper node
        wrapperNode = treeutil.compileString(stringStart+stringReplacement+stringStop, id + "||stringopt")

        # Reorganize structure
        funcBody = wrapperNode.getChild("operand").getChild("group").getChild("function").getChild("body").getChild("block")
        if tree.hasChildren():
            for child in copy.copy(tree.children):
                tree.removeChild(child)
                funcBody.addChild(child)

        # Add wrapper to tree
        tree.addChild(wrapperNode)
Exemple #6
0
def replace(node, stringList, var="$", verbose=False):
    if node.type == "constant" and node.get("constantType") == "string":
        if node.get("detail") == "singlequotes":
            quote = "'"
        elif node.get("detail") == "doublequotes":
            quote = '"'
        oldvalue = "%s%s%s" % (quote, node.get("value"), quote)

        for pos,item in enumerate(stringList):
            if item["value"] == oldvalue:
                newvalue = "%s[%s]" % (var, pos)  # this is only for output, and is bogus

                if verbose:
                    poldvalue = oldvalue
                    if isinstance(poldvalue, unicode):
                        poldvalue = poldvalue.encode("utf-8")
                    print "    - Replace: %s => %s" % (poldvalue, newvalue)

                line = node.get("line")


                # generate identifier
                replacement_ident = treeutil.compileString("SSSS_%s" % pos)
                replacement_ident.set("line", node.get("line"))
                replacement_ident.set("column", node.get("column"))

                # replace node
                node.parent.replaceChild(node, replacement_ident)
                break

    if check(node, verbose):
        for child in node.children:
            replace(child, stringList, var, verbose)
Exemple #7
0
def _optimizeStrings(tree, id):
    stringMap = stringoptimizer.search(tree)

    if len(stringMap) == 0:
        return

    stringList = stringoptimizer.sort(stringMap)
    stringoptimizer.replace(tree, stringList)

    # Build JS string fragments
    stringStart = "(function(){"
    stringReplacement = stringoptimizer.replacement(stringList)
    stringStop = "})();"

    # Compile wrapper node
    wrapperNode = treeutil.compileString(
        stringStart + stringReplacement + stringStop, id + "||stringopt")

    # Reorganize structure
    funcBody = wrapperNode.getChild("operand").getChild("group").getChild(
        "function").getChild("body").getChild("block")
    if tree.hasChildren():
        for child in copy.copy(tree.children):
            tree.removeChild(child)
            funcBody.addChild(child)

    # Add wrapper to tree
    tree.addChild(wrapperNode)
def process(tree, id_):
    # refresh scopes to get a check-set
    tree = scopes.create_scopes(tree)
    check_set = tree.scope.all_var_names()
    check_set.update(lang.RESERVED.keys())

    # assuming a <file> or <block> node
    statementsNode = tree.getChild("statements")

    # create a map for strings to var names
    stringMap = search(statementsNode, verbose=False)
    if len(stringMap) == 0:
        return tree

    # apply the vars
    #stringList = sort(stringMap)
    replace(statementsNode, stringMap, check_set)

    # create a 'var' decl for the string vars
    stringReplacement = replacement(stringMap)
    repl_tree = treeutil.compileString(stringReplacement, id_ + "||stringopt")

    # ensure a wrapping closure
    closure, closure_block = treeutil.ensureClosureWrapper(statementsNode.children)
    statementsNode.removeAllChildren()
    statementsNode.addChild(closure)

    # add 'var' decl to closure
    closure_block.addChild(repl_tree, 0)  # 'var ...'; decl to front of statement list

    return tree
Exemple #9
0
def process(tree, id_):
    # refresh scopes to get a check-set
    tree = scopes.create_scopes(tree)
    check_set = tree.scope.all_var_names()
    check_set.update(lang.RESERVED.keys())

    # assuming a <file> or <block> node
    statementsNode = tree.getChild("statements")

    # create a map for strings to var names
    stringMap = search(statementsNode)
    if len(stringMap) == 0:
        return tree

    # apply the vars
    #stringList = sort(stringMap)
    replace(statementsNode, stringMap, check_set)

    # create a 'var' decl for the string vars
    stringReplacement = replacement(stringMap)
    repl_tree = treeutil.compileString(stringReplacement, id_ + "||stringopt")

    # ensure a wrapping closure
    closure, closure_block = treeutil.ensureClosureWrapper(
        statementsNode.children)
    statementsNode.removeAllChildren()
    statementsNode.addChild(closure)

    # add 'var' decl to closure
    closure_block.addChild(repl_tree,
                           0)  # 'var ...'; decl to front of statement list

    return tree
Exemple #10
0
def optimizeConstruct(node, superClass, methodName, classDefNodes):
    patchCount = 0

    # Need to run through all the nodes, to skip embedded qx.*.define(),
    # which will be treated separately

    # Handle Node

    # skip embedded qx.*.define()
    if node in classDefNodes:
        return 0

    elif node.type == "variable" and node.hasParentContext("call/operand"):

        varName, complete = treeutil.assembleVariable(node)
        if not (complete and varName == "this.base"):
            return 0

        call = node.parent.parent

        try:
            firstArgName = treeutil.selectNode(call, "params/1/identifier/@name")
        except tree.NodeAccessException:
            return 0

        if firstArgName != "arguments":
            return 0

        # "construct"
        if methodName == "construct":
            newCall = treeutil.compileString("%s.call()" % superClass)
        # "member"
        else:
            newCall = treeutil.compileString("%s.prototype.%s.call()" % (superClass, methodName))
        newCall.replaceChild(newCall.getChild("params"), call.getChild("params"))  # replace with old arglist
        treeutil.selectNode(newCall, "params/1/identifier").set("name", "this")  # arguments -> this
        call.parent.replaceChild(call, newCall)
        patchCount += 1

    # Handle Children
    if node.hasChildren():
        for child in node.children:
            patchCount += optimizeConstruct(child, superClass, methodName, classDefNodes)

    return patchCount
Exemple #11
0
def replace(node, stringMap, check_set=set(), verbose=False):
    mapper = NameMapper(check_set)
    for cstring,value in stringMap.items():
        var_name = mapper.mapper(cstring)
        value[0] = var_name  # memoize var_name in stringMap
        for node in value[1]:
            repl_ident = treeutil.compileString(var_name)
            repl_ident.set("line", node.get("line"))
            repl_ident.set("column", node.get("column"))
            node.parent.replaceChild(node, repl_ident)
Exemple #12
0
def replace(node, stringMap, check_set=set(), verbose=False):
    mapper = NameMapper(check_set)
    for cstring, value in stringMap.items():
        var_name = mapper.mapper(cstring)
        value[0] = var_name  # memoize var_name in stringMap
        for node in value[1]:
            repl_ident = treeutil.compileString(var_name)
            repl_ident.set("line", node.get("line"))
            repl_ident.set("column", node.get("column"))
            node.parent.replaceChild(node, repl_ident)
Exemple #13
0
def patch(node):
    patchCount = 0

    this_base_vars = treeutil.findVariable(node, "this.base")
    for var in this_base_vars:
        if var.parent.type == "operand" and var.parent.parent.type == "call":
            call = var.parent.parent
            try:
                firstArgName = treeutil.selectNode(
                    call, "params/1/identifier/@name")
            except tree.NodeAccessException:
                continue

            if firstArgName != "arguments":
                continue

            newCall = treeutil.compileString(
                "arguments.callee.base.call(this)")
            newCall.replaceChild(newCall.getChild("params"),
                                 call.getChild("params"))
            treeutil.selectNode(newCall,
                                "params/1/identifier").set("name", "this")
            call.parent.replaceChild(call, newCall)
            patchCount += 1

    this_self_vars = treeutil.findVariable(node, "this.self")
    for var in this_self_vars:
        if var.parent.type == "operand" and var.parent.parent.type == "call":
            call = var.parent.parent
            try:
                firstArgName = treeutil.selectNode(
                    call, "params/1/identifier/@name")
            except tree.NodeAccessException:
                continue

            if firstArgName != "arguments":
                continue

            newCall = treeutil.compileString("arguments.callee.self")
            call.parent.replaceChild(call, newCall)
            patchCount += 1

    return patchCount
def patch(node):
    patchCount = 0

    this_base_vars = treeutil.findVariable(node, "this.base")
    for var in this_base_vars:
        if var.parent.type == "operand" and var.parent.parent.type == "call":
            call = var.parent.parent
            try:
                firstArgName = treeutil.selectNode(call, "params/1/identifier/@name")
            except tree.NodeAccessException:
                continue

            if firstArgName != "arguments":
                continue

            newCall = treeutil.compileString("arguments.callee.base.call(this)")
            newCall.replaceChild(newCall.getChild("params"), call.getChild("params"))
            treeutil.selectNode(newCall, "params/1/identifier").set("name", "this")
            call.parent.replaceChild(call, newCall)
            patchCount += 1

    this_self_vars = treeutil.findVariable(node, "this.self")
    for var in this_self_vars:
        if var.parent.type == "operand" and var.parent.parent.type == "call":
            call = var.parent.parent
            try:
                firstArgName = treeutil.selectNode(call, "params/1/identifier/@name")
            except tree.NodeAccessException:
                continue

            if firstArgName != "arguments":
                continue

            newCall = treeutil.compileString("arguments.callee.self")
            call.parent.replaceChild(call, newCall)
            patchCount += 1

    return patchCount
Exemple #15
0
def generateProperty(name, config, members, method):
    if not method in ["get", "is"]:
        return

    # print "Generate %s for %s" % (method, name)

    code = "function(){"

    if "inheritable" in config:
        code += 'if(this.$$inherit_' + name + '!==undefined)'
        code += 'return this.$$inherit_' + name + ';'
        code += 'else '

    code += 'if(this.$$user_' + name + '!==undefined)'
    code += 'return this.$$user_' + name + ';'

    if "themeable" in config:
        code += 'else if(this.$$theme_' + name + '!==undefined)'
        code += 'return this.$$theme_' + name + ';'

    if not "init" in config and "deferredInit" in config:
        code += 'else if(this.$$init_' + name + '!==undefined)'
        code += 'return this.$$init_' + name + ';'

    code += 'else '

    if "init" in config:
        code += 'return this.$$init_' + name + ';'
    else:
        code += 'return null;'

    code += "}"

    func = treeutil.compileString(code)
    pair = treeutil.createPair(method + name[0].upper() + name[1:], func)

    members.addChild(pair)
def generateProperty(name, config, members, method):
    if not method in ["get", "is"]:
        return
    
    # print "Generate %s for %s" % (method, name)
    
    code = "function(){"
    
    if "inheritable" in config:
        code += 'if(this.$$inherit_' + name + '!==undefined)'
        code += 'return this.$$inherit_' + name + ';'
        code += 'else '

    code += 'if(this.$$user_' + name + '!==undefined)'
    code += 'return this.$$user_' + name + ';'

    if "themeable" in config:
        code += 'else if(this.$$theme_' + name + '!==undefined)'
        code += 'return this.$$theme_' + name + ';'

    if not "init" in config and "deferredInit" in config:
        code += 'else if(this.$$init_' + name + '!==undefined)'
        code += 'return this.$$init_' + name + ';'

    code += 'else '

    if "init" in config:
        code += 'return this.$$init_' + name + ';'
    else:
        code += 'return null;'
        
    code += "}"

    func = treeutil.compileString(code)
    pair = treeutil.createPair(method + name[0].upper() + name[1:], func)
    
    members.addChild(pair)
Exemple #17
0
def generateProperty(name, config, members, method):
    if not method in ["get", "is"]:
        return

    # print "Generate %s for %s" % (method, name)

    code = "function(){"

    if config.has_key("inheritable"):
        code += "if(this.$$inherit_" + name + "!==undefined)"
        code += "return this.$$inherit_" + name + ";"
        code += "else "

    code += "if(this.$$user_" + name + "!==undefined)"
    code += "return this.$$user_" + name + ";"

    if config.has_key("themeable"):
        code += "else if(this.$$theme_" + name + "!==undefined)"
        code += "return this.$$theme_" + name + ";"

    if not config.has_key("init") and config.has_key("deferredInit"):
        code += "else if(this.$$init_" + name + "!==undefined)"
        code += "return this.$$init_" + name + ";"

    code += "else "

    if config.has_key("init"):
        code += "return this.$$init_" + name + ";"
    else:
        code += "return null;"

    code += "}"

    func = treeutil.compileString(code)
    pair = treeutil.createPair(method + name[0].upper() + name[1:], func)

    members.addChild(pair)
Exemple #18
0
    def findClassForFeature(self, featureId, variants, classMaps):

        # get the method name
        clazzId = self.id
        if  featureId == u'':  # corner case: bare class reference outside "new ..."
            return clazzId, featureId
        # TODO: The next doesn't provide much, qx.Class.getInstance has no new dependencies
        # currently (aside from "new this", which I cannot relate back to 'construct'
        # ATM). Leave it in anyway, to not break bug#5660.
        #elif featureId == "getInstance": # corner case: singletons get this from qx.Class
        #    clazzId = "qx.Class"
        elif featureId == "getInstance" and self.type == "singleton":
            featureId = "construct"
        elif featureId in ('call', 'apply'):  # this might get overridden, oh well...
            clazzId = "Function"
        # TODO: getter/setter are also not lexically available!
        # handle .call() ?!
        if clazzId not in self._classesObj: # can't further process non-qooxdoo classes
            # TODO: maybe this should better use something like isInterestingIdentifier()
            # to invoke the same machinery for filtering references like in other places
            return None, None

        # early return if class id is finalized
        if clazzId != self.id:
            classObj = self._classesObj[clazzId]
            featureNode = self.getFeatureNode(featureId, variants)
            if featureNode:
                return clazzId, featureNode
            else:
                return None, None

        # now try this class
        if self.id in classMaps:
            classMap = classMaps[self.id]
        else:
            classMap = classMaps[self.id] = self.getClassMap (variants)
        featureNode = self.getFeatureNode(featureId, variants, classMap)
        if featureNode:
            return self.id, featureNode

        if featureId == 'construct':  # constructor requested, but not supplied in class map
            # supply the default constructor
            featureNode = treeutil.compileString("function(){this.base(arguments);}", self.path)
            return self.id, featureNode

        # inspect inheritance/mixins
        parents = []
        extendVal = classMap.get('extend', None)
        if extendVal:
            extendVal = treeutil.variableOrArrayNodeToArray(extendVal)
            parents.extend(extendVal)
            # this.base calls
            if featureId == "base":
                classId = parents[0]  # first entry must be super-class
                if classId in self._classesObj:
                    return self._classesObj[classId].findClassForFeature('construct', variants, classMaps)
                else:
                    return None, None
        includeVal = classMap.get('include', None)
        if includeVal:
            # 'include' value according to Class spec.
            if includeVal.type in ('variable', 'array'):
                includeVal = treeutil.variableOrArrayNodeToArray(includeVal)
            
            # assume qx.core.Environment.filter() call
            else:
                filterMap = variantoptimizer.getFilterMap(includeVal, self.id)
                includeSymbols = []
                for key, node in filterMap.items():
                    # only consider true or undefined 
                    #if key not in variants or (key in variants and bool(variants[key]):
                    # map value has to be value/variable
                    variable =  node.children[0]
                    assert variable.type == "variable"
                    symbol, isComplete = treeutil.assembleVariable(variable)
                    assert isComplete
                    includeSymbols.append(symbol)
                includeVal = includeSymbols

            parents.extend(includeVal)

        # go through all ancestors
        for parClass in parents:
            if parClass not in self._classesObj:
                continue
            parClassObj = self._classesObj[parClass]
            rclass, keyval = parClassObj.findClassForFeature(featureId, variants, classMaps)
            if rclass:
                return rclass, keyval
        return None, None
Exemple #19
0
    def findClassForFeature(self, featureId, variants, classMaps):

        # get the method name
        clazzId = self.id
        if  featureId == u'':  # corner case: bare class reference outside "new ..."
            return clazzId, featureId
        # TODO: The next doesn't provide much, qx.Class.getInstance has no new dependencies
        # currently (aside from "new this", which I cannot relate back to 'construct'
        # ATM). Leave it in anyway, to not break bug#5660.
        #elif featureId == "getInstance": # corner case: singletons get this from qx.Class
        #    clazzId = "qx.Class"
        elif featureId == "getInstance" and self.type == "singleton":
            featureId = "construct"
        elif featureId in ('call', 'apply'):  # this might get overridden, oh well...
            clazzId = "Function"
        # TODO: getter/setter are also not lexically available!
        # handle .call() ?!
        if clazzId not in ClassesAll: # can't further process non-qooxdoo classes
            # TODO: maybe this should better use something like isInterestingIdentifier()
            # to invoke the same machinery for filtering references like in other places
            return None, None

        # early return if class id is finalized
        if clazzId != self.id:
            classObj = ClassesAll[clazzId]
            featureNode = self.getFeatureNode(featureId, variants)
            if featureNode:
                return clazzId, featureNode
            else:
                return None, None

        # now try this class
        if self.id in classMaps:
            classMap = classMaps[self.id]
        else:
            classMap = classMaps[self.id] = self.getClassMap (variants)
        featureNode = self.getFeatureNode(featureId, variants, classMap)
        if featureNode:
            return self.id, featureNode

        if featureId == 'construct':  # constructor requested, but not supplied in class map
            # supply the default constructor
            featureNode = treeutil.compileString("function(){this.base(arguments);}", self.path)
            # the next is a hack to provide minimal scope info
            featureNode.set("treegenerator_tag", 1)
            featureNode = scopes.create_scopes(featureNode)
            return self.id, featureNode

        # inspect inheritance/mixins
        parents = []
        extendVal = classMap.get('extend', None)
        if extendVal:
            extendVal = treeutil.variableOrArrayNodeToArray(extendVal)
            parents.extend(extendVal)
            # this.base calls
            if featureId == "base":
                classId = parents[0]  # first entry must be super-class
                if classId in ClassesAll:
                    return ClassesAll[classId].findClassForFeature('construct', variants, classMaps)
                else:
                    return None, None
        includeVal = classMap.get('include', None)
        if includeVal:
            # 'include' value according to Class spec.
            if includeVal.type in NODE_VARIABLE_TYPES + ('array',):
                includeVal = treeutil.variableOrArrayNodeToArray(includeVal)

            # assume qx.core.Environment.filter() call
            else:
                filterMap = variantoptimizer.getFilterMap(includeVal, self.id)
                includeSymbols = []
                for key, node in filterMap.items():
                    # only consider true or undefined
                    #if key not in variants or (key in variants and bool(variants[key]):
                    # map value has to be value/variable
                    variable =  node.children[0]
                    assert variable.isVar()
                    symbol, isComplete = treeutil.assembleVariable(variable)
                    assert isComplete
                    includeSymbols.append(symbol)
                includeVal = includeSymbols

            parents.extend(includeVal)

        # go through all ancestors
        for parClass in parents:
            if parClass not in ClassesAll:
                continue
            parClassObj = ClassesAll[parClass]
            rclass, keyval = parClassObj.findClassForFeature(featureId, variants, classMaps)
            if rclass:
                return rclass, keyval
        return None, None
Exemple #20
0
        newCall.replaceChild(newCall.getChild("params"), call.getChild("params"))  # replace with old arglist
        treeutil.selectNode(newCall, "params/1/identifier").set("name", "this")  # arguments -> this
        call.parent.replaceChild(call, newCall)
        patchCount += 1

    # Handle Children
    if node.hasChildren():
        for child in node.children:
            patchCount += optimizeConstruct(child, superClass, methodName, classDefNodes)

    return patchCount


if __name__ == "__main__":
    cls = """qx.Class.define("qx.Car", {
      extend: qx.core.Object,
      construct : function() {
        this.base(arguments, "2")
      },
      members : {
        foo : function() {
          return this.base(arguments)
        }
      }
    })"""

    node = treeutil.compileString(cls)
    patch(node)

    print node.toJavascript()
    def findClassForFeature(self, featureId, variants, classMaps):

        # get the method name
        clazzId = self.id
        if  featureId == u'':  # corner case: bare class reference outside "new ..."
            return clazzId, featureId
        elif featureId == "getInstance": # corner case: singletons get this from qx.Class
            clazzId = "qx.Class"
        elif featureId in ('call', 'apply'):  # this might get overridden, oh well...
            clazzId = "Function"
        # TODO: getter/setter are also not lexically available!
        # handle .call() ?!
        if clazzId not in self._classesObj: # can't further process non-qooxdoo classes
            # TODO: maybe this should better use something like isInterestingIdentifier()
            # to invoke the same machinery for filtering references like in other places
            return None, None

        # early return if class id is finalized
        if clazzId != self.id:
            classObj = self._classesObj[clazzId]
            featureNode = self.getFeatureNode(featureId, variants)
            if featureNode:
                return clazzId, featureNode
            else:
                return None, None

        # now try this class
        if self.id in classMaps:
            classMap = classMaps[self.id]
        else:
            classMap = classMaps[self.id] = self.getClassMap (variants)
        featureNode = self.getFeatureNode(featureId, variants, classMap)
        if featureNode:
            return self.id, featureNode

        if featureId == 'construct':  # constructor requested, but not supplied in class map
            # supply the default constructor
            featureNode = treeutil.compileString("function(){this.base(arguments);}", self.path)
            return self.id, featureNode

        # inspect inheritance/mixins
        parents = []
        extendVal = classMap.get('extend', None)
        if extendVal:
            extendVal = treeutil.variableOrArrayNodeToArray(extendVal)
            parents.extend(extendVal)
            # this.base calls
            if featureId == "base":
                classId = parents[0]  # first entry must be super-class
                if classId in self._classesObj:
                    return self._classesObj[classId].findClassForFeature('construct', variants, classMaps)
                else:
                    return None, None
        includeVal = classMap.get('include', None)
        if includeVal:
            # 'include' value according to Class spec.
            if includeVal.type in ('variable', 'array'):
                includeVal = treeutil.variableOrArrayNodeToArray(includeVal)
            
            # assume qx.core.Variant.select() call
            else:
                _, branchMap = variantoptimizer.getSelectParams(includeVal)
                includeVal = set()
                for key in branchMap: # just pick up all possible include values
                    includeVal.update(treeutil.variableOrArrayNodeToArray(branchMap[key]))
                includeVal = list(includeVal)

            parents.extend(includeVal)

        # go through all ancestors
        for parClass in parents:
            if parClass not in self._classesObj:
                continue
            parClassObj = self._classesObj[parClass]
            rclass, keyval = parClassObj.findClassForFeature(featureId, variants, classMaps)
            if rclass:
                return rclass, keyval
        return None, None
Exemple #22
0
            "name", "this")  # arguments -> this
        call.parent.replaceChild(call, newCall)
        patchCount += 1

    # Handle Children
    if node.hasChildren():
        for child in node.children:
            patchCount += optimizeConstruct(child, superClass, methodName,
                                            classDefNodes)

    return patchCount


if __name__ == "__main__":
    cls = """qx.Class.define("qx.Car", {
      extend: qx.core.Object,
      construct : function() {
        this.base(arguments, "2")
      },
      members : {
        foo : function() {
          return this.base(arguments)
        }
      }
    })"""

    node = treeutil.compileString(cls)
    patch(node)

    print node.toJavascript()