def handleConstructor(ctorItem, classNode): if ctorItem and ctorItem.type == "function": commentAttributes = comment.parseNode(ctorItem.parent.parent) ctor = handleFunction(ctorItem, "ctor", commentAttributes, classNode) removeErrors(ctor) ctor.set("isCtor", True) classNode.addListChild("constructor", ctor)
def handleConstantDefinition(item, classNode): if (item.type == "assignment"): # This is a "normal" constant definition leftItem = item.getFirstListChild("left") name = leftItem.children[len(leftItem.children) - 1].get("name") valueNode = item.getChild("right") elif (item.type == "keyvalue"): # This is a constant definition of a map-style class (like qx.Const) name = item.get("key") valueNode = item.getChild("value") if not name.isupper(): return node = tree.Node("constant") node.set("name", name) value = None if valueNode.hasChild("constant"): node.set("value", valueNode.getChild("constant").get("value")) node.set("type", valueNode.getChild("constant").get("constantType").capitalize()) commentAttributes = comment.parseNode(item) description = comment.getAttrib(commentAttributes, "description") addTypeInfo(node, description, item) handleDeprecated(node, commentAttributes) handleAccess(node, commentAttributes) classNode.addListChild("constants", node)
def handleConstantDefinition(item, classNode): if (item.type == "assignment"): # This is a "normal" constant definition leftItem = item.getFirstListChild("left") name = leftItem.children[len(leftItem.children) - 1].get("name") valueNode = item.getChild("right") elif (item.type == "keyvalue"): # This is a constant definition of a map-style class (like qx.Const) name = item.get("key") valueNode = item.getChild("value") if not name.isupper(): return node = tree.Node("constant") node.set("name", name) value = None if valueNode.hasChild("constant"): node.set("value", valueNode.getChild("constant").get("value")) node.set( "type", valueNode.getChild("constant").get("constantType").capitalize()) commentAttributes = comment.parseNode(item) description = comment.getAttrib(commentAttributes, "description") addTypeInfo(node, description, item) handleDeprecated(node, commentAttributes) handleAccess(node, commentAttributes) classNode.addListChild("constants", node)
def handleEvents(item, classNode): for key, value in mapNodeToMap(item).items(): keyvalue = value.parent value = value.getFirstChild(True, True).get("value") node = tree.Node("event") commentAttributes = comment.parseNode(keyvalue) try: desc = commentAttributes[0]["text"] except (IndexError, KeyError): desc = None addError(node, "Documentation is missing.", item) if desc != None: node.addChild(tree.Node("desc").set("text", desc)) node.set("name", key) typesNode = tree.Node("types") node.addChild(typesNode) itemNode = tree.Node("entry") typesNode.addChild(itemNode) itemNode.set("type", value) handleDeprecated(node, commentAttributes) handleAccess(node, commentAttributes) classNode.addListChild("events", node)
def handleStatics(item, classNode): for key, value in mapNodeToMap(item).items(): keyvalue = value.parent value = value.getFirstChild() commentAttributes = comment.parseNode(keyvalue) # handle @signature if value.type != "function": for docItem in commentAttributes: if docItem["category"] == "signature": value = compileString(docItem["text"][3:-4] + "{}") # Function if value.type == "function": node = handleFunction(value, key, commentAttributes, classNode) node.set("isStatic", True) if classNode.get("type", False) == "mixin": node.set("isMixin", True) classNode.addListChild("methods-static", node) # Constant elif key.isupper(): handleConstantDefinition(keyvalue, classNode)
def handleConstructor(ctorItem, classNode): if ctorItem and ctorItem.type == "function": commentAttributes = comment.parseNode(ctorItem.parent.parent) ctor = handleFunction(ctorItem, "ctor", commentAttributes, classNode, reportMissingDesc=False) ctor.set("isCtor", True) classNode.addListChild("constructor", ctor)
def documentApplyMethod(methodNode, prop): if itemHasAnyDocs(methodNode): return firstParam = selectNode(methodNode, "params/param[1]/@name") if firstParam is None: firstParam = "value" secondParam = selectNode(methodNode, "params/param[2]/@name") if secondParam is None: secondParam = "old" paramType = prop.get("check", False) if paramType is None or paramType == "Custom check function.": paramType = "var" functionCode = """/** * Applies changes of the property value of the property <code>%(shortPropName)s</code>. * * For further details take a look at the property definition: {@link #%(propName)s}. * * @param %(firstParamName)s {%(paramType)s} new value of the property * @param %(secondParamName)s {%(paramType)s} previous value of the property (null if it was not yet set). */ function(%(firstParamName)s, %(secondParamName)s) {}""" % ( { "firstParamName": firstParam, "secondParamName": secondParam, "paramType": paramType, "shortPropName": prop.get("name"), "propName": methodNode.get("name") }) node = compileString(functionCode) commentAttributes = comment.parseNode(node) docNode = handleFunction(node, methodNode.get("name"), commentAttributes, selectNode(methodNode, "../..")) oldParams = methodNode.getChild("params", False) if oldParams: methodNode.replaceChild(oldParams, docNode.getChild("params")) else: methodNode.addChild(docNode.getChild("params")) oldDesc = methodNode.getChild("desc", False) if oldDesc: methodNode.replaceChild(oldDesc, docNode.getChild("desc")) else: methodNode.addChild(docNode.getChild("desc"))
def documentApplyMethod(methodNode, prop): if itemHasAnyDocs(methodNode): return firstParam = selectNode(methodNode, "params/param[1]/@name") if firstParam is None: firstParam = "value" secondParam = selectNode(methodNode, "params/param[2]/@name") if secondParam is None: secondParam = "old" paramType = prop.get("check", False) if paramType is None or paramType == "Custom check function.": paramType = "var" functionCode = """/** * Applies changes of the property value of the property <code>%(shortPropName)s</code>. * * For further details take a look at the property definition: {@link #%(propName)s}. * * @param %(firstParamName)s {%(paramType)s} new value of the property * @param %(secondParamName)s {%(paramType)s} previous value of the property (null if it was not yet set). */ function(%(firstParamName)s, %(secondParamName)s) {}""" % ({ "firstParamName": firstParam, "secondParamName": secondParam, "paramType": paramType, "shortPropName": prop.get("name"), "propName": methodNode.get("name") }) node = compileString(functionCode) commentAttributes = comment.parseNode(node) docNode = handleFunction(node, methodNode.get("name"), commentAttributes, selectNode(methodNode, "../..")) oldParams = methodNode.getChild("params", False) if oldParams: methodNode.replaceChild(oldParams, docNode.getChild("params")) else: methodNode.addChild(docNode.getChild("params")) oldDesc = methodNode.getChild("desc", False) if oldDesc: methodNode.replaceChild(oldDesc, docNode.getChild("desc")) else: methodNode.addChild(docNode.getChild("desc"))
def handleProperties(item, classNode): for propName, value in mapNodeToMap(item).items(): keyvalue = value.parent value = value.getFirstChild() if value.type != "map": continue propDefinition = mapNodeToMap(value) #print propName, propDefinition if propDefinition.has_key("group"): node = handlePropertyGroup(propName, propDefinition, classNode) node.set("propertyType", "group") groupMembers = [ member[1:-1] for member in node.get("group").split(",") ] generateGroupPropertyMethod(propName, groupMembers, node.get("mode", False), classNode) generatePropertyMethods(propName, classNode, ["reset"]) else: node = handlePropertyDefinitionNew(propName, propDefinition, classNode) node.set("propertyType", "new") if node.get("refine", False) != "true": generatePropertyMethods(propName, classNode, ["set", "get", "init", "reset"]) if node.get("check", False) == "Boolean": generatePropertyMethods(propName, classNode, ["toggle", "is"]) if classNode.get("type", False) == "mixin": node.set("isMixin", True) # If the description has a type specified then take this type # (and not the one extracted from the paramsMap) commentAttributes = comment.parseNode(keyvalue) addTypeInfo(node, comment.getAttrib(commentAttributes, "description"), item) handleDeprecated(node, commentAttributes) handleAccess(node, commentAttributes) classNode.addListChild("properties", node)
def generateGroupPropertyMethod(propertyName, groupMembers, mode, classNode): if propertyName[:2] == "__": access = "__" functionName = propertyName[2:] elif propertyName[:1] == "_": access = "_" functionName = propertyName[1:] else: access = "" functionName = propertyName functionName = access + "set" + functionName[0].upper() + functionName[1:] functionTemplate = """/** * Sets the values of the property group <code>%(name)s</code>. * %(modeDoc)s * For further details take a look at the property definition: {@link #%(name)s}. * %(params)s */ function (%(paramList)s) {}; """ paramsTemplate = " * @param %s {var} Sets the value of the property {@link #%s}." paramsDef = [paramsTemplate % (name, name) for name in groupMembers] if mode == "shorthand": modeDoc = "\n * This setter supports a shorthand mode compatible with the way margins and paddins are set in CSS.\n *" else: modeDoc = "" functionCode = functionTemplate % ({ "name": propertyName, "modeDoc": modeDoc, "params": "\n".join(paramsDef), "paramList": ", ".join(groupMembers) }) functionNode = compileString(functionCode) commentAttributes = comment.parseNode(functionNode) docNode = handleFunction(functionNode, functionName, commentAttributes, classNode) docNode.set("fromProperty", propertyName) classNode.addListChild("methods", docNode)
def generateGroupPropertyMethod(propertyName, groupMembers, mode, classNode): if propertyName[:2] == "__": access = "__" functionName = propertyName[2:] elif propertyName[:1] == "_": access = "_" functionName = propertyName[1:] else: access = "" functionName = propertyName functionName = access + "set" + functionName[0].upper() + functionName[1:] functionTemplate = """/** * Sets the values of the property group <code>%(name)s</code>. * %(modeDoc)s * For further details take a look at the property definition: {@link #%(name)s}. * %(params)s */ function (%(paramList)s) {}; """ paramsTemplate = " * @param %s {var} Sets the value of the property {@link #%s}." paramsDef = [paramsTemplate % (name, name) for name in groupMembers] if mode == "shorthand": modeDoc = "\n * This setter supports a shorthand mode compatible with the way margins and paddins are set in CSS.\n *" else: modeDoc = "" functionCode = functionTemplate % ({ "name" : propertyName, "modeDoc" : modeDoc, "params" : "\n".join(paramsDef), "paramList" : ", ".join(groupMembers) }) functionNode = compileString(functionCode) commentAttributes = comment.parseNode(functionNode) docNode = handleFunction(functionNode, functionName, commentAttributes, classNode) docNode.set("fromProperty", propertyName) classNode.addListChild("methods", docNode)
def handleSingleton(classNode, docTree): if classNode.get("isSingleton", False) == True: className = classNode.get("fullName") functionCode = """/** * Returns a singleton instance of this class. On the first call the class * is instantiated by calling the constructor with no arguments. All following * calls will return this instance. * * This method has been added by setting the "type" key in the class definition * ({@link qx.Class#define}) to "singleton". * * @type static * @return {%s} The singleton instance of this class. */ function() {}""" % className node = compileString(functionCode) commentAttributes = comment.parseNode(node) docNode = handleFunction(node, "getInstance", commentAttributes, classNode) docNode.set("isStatic", True) classNode.addListChild("methods-static", docNode)
def handleProperties(item, classNode): for propName, value in mapNodeToMap(item).items(): keyvalue = value.parent value = value.getFirstChild() if value.type != "map": continue propDefinition = mapNodeToMap(value) #print propName, propDefinition if propDefinition.has_key("group"): node = handlePropertyGroup(propName, propDefinition, classNode) node.set("propertyType", "group") groupMembers = [member[1:-1] for member in node.get("group").split(",")] generateGroupPropertyMethod(propName, groupMembers, node.get("mode", False), classNode) generatePropertyMethods(propName, classNode, ["reset"]) else: node = handlePropertyDefinitionNew(propName, propDefinition, classNode) node.set("propertyType", "new") if node.get("refine", False) != "true": generatePropertyMethods(propName, classNode, ["set", "get", "init", "reset"]) if node.get("check", False) == "Boolean": generatePropertyMethods(propName, classNode, ["toggle", "is"]) if classNode.get("type", False) == "mixin": node.set("isMixin", True) # If the description has a type specified then take this type # (and not the one extracted from the paramsMap) commentAttributes = comment.parseNode(keyvalue) addTypeInfo(node, comment.getAttrib(commentAttributes, "description"), item) handleDeprecated(node, commentAttributes) handleAccess(node, commentAttributes) classNode.addListChild("properties", node)
def generatePropertyMethods(propertyName, classNode, generatedMethods): if propertyName[:2] == "__": access = "__" name = propertyName[2:] elif propertyName[:1] == "_": access = "_" name = propertyName[1:] else: access = "" name = propertyName name = name[0].upper() + name[1:] propData = { access + "set" + name : """/** * Sets the user value of the property <code>%s</code>. * * For further details take a look at the property definition: {@link #%s}. * * @param value {var} New value for property <code>%s</code>. * @return {var} The unmodified incoming value. */ function (value) {}; """ % (propertyName, propertyName, propertyName), access + "get" + name : """/** * Returns the (computed) value of the property <code>%s</code>. * * For further details take a look at the property definition: {@link #%s}. * * @return {var} (Computed) value of <code>%s</code>. */ function () {}; """ % (propertyName, propertyName, propertyName), access + "reset" + name : """/** * Resets the user value of the property <code>%s</code>. * * The computed value falls back to the next available value e.g. appearance, init or * inheritance value depeneding on the property configuration and value availability. * * For further details take a look at the property definition: {@link #%s}. * * @return {void} */ function () {}; """ % (propertyName, propertyName), access + "init" + name : """/** * Calls the apply method and dispatches the change event of the property <code>%s</code> * with the default value defined by the class developer. This function can * only be called from the constructor of a class. * * For further details take a look at the property definition: {@link #%s}. * * @protected * @param value {var} Initial value for property <code>%s</code>. * @return {var} the default value */ function (value) {}; """ % (propertyName, propertyName, propertyName), access + "toggle" + name : """/** * Toggles the (computed) value of the boolean property <code>%s</code>. * * For further details take a look at the property definition: {@link #%s}. * * @return {Boolean} the new value */ function () {}; """ % (propertyName, propertyName), access + "is" + name : """/** * Check whether the (computed) value of the boolean property <code>%s</code> equals <code>true</code>. * * For further details take a look at the property definition: {@link #%s}. * * @return {Boolean} Whether the property equals <code>true</code>. */ function () {}; """ % (propertyName, propertyName) } for funcName in generatedMethods: funcName = access + funcName + name functionCode = propData[funcName] node = compileString(functionCode) commentAttributes = comment.parseNode(node) docNode = handleFunction(node, funcName, commentAttributes, classNode) docNode.set("fromProperty", propertyName) classNode.addListChild("methods", docNode)
def generatePropertyMethods(propertyName, classNode, generatedMethods): if propertyName[:2] == "__": access = "__" name = propertyName[2:] elif propertyName[:1] == "_": access = "_" name = propertyName[1:] else: access = "" name = propertyName name = name[0].upper() + name[1:] propData = { access + "set" + name: """/** * Sets the user value of the property <code>%s</code>. * * For further details take a look at the property definition: {@link #%s}. * * @param value {var} New value for property <code>%s</code>. * @return {var} The unmodified incoming value. */ function (value) {}; """ % (propertyName, propertyName, propertyName), access + "get" + name: """/** * Returns the (computed) value of the property <code>%s</code>. * * For further details take a look at the property definition: {@link #%s}. * * @return {var} (Computed) value of <code>%s</code>. */ function () {}; """ % (propertyName, propertyName, propertyName), access + "reset" + name: """/** * Resets the user value of the property <code>%s</code>. * * The computed value falls back to the next available value e.g. appearance, init or * inheritance value depeneding on the property configuration and value availability. * * For further details take a look at the property definition: {@link #%s}. * * @return {void} */ function () {}; """ % (propertyName, propertyName), access + "init" + name: """/** * Calls the apply method and dispatches the change event of the property <code>%s</code> * with the default value defined by the class developer. This function can * only be called from the constructor of a class. * * For further details take a look at the property definition: {@link #%s}. * * @protected * @param value {var} Initial value for property <code>%s</code>. * @return {var} the default value */ function (value) {}; """ % (propertyName, propertyName, propertyName), access + "toggle" + name: """/** * Toggles the (computed) value of the boolean property <code>%s</code>. * * For further details take a look at the property definition: {@link #%s}. * * @return {Boolean} the new value */ function () {}; """ % (propertyName, propertyName), access + "is" + name: """/** * Check whether the (computed) value of the boolean property <code>%s</code> equals <code>true</code>. * * For further details take a look at the property definition: {@link #%s}. * * @return {Boolean} Whether the property equals <code>true</code>. */ function () {}; """ % (propertyName, propertyName) } for funcName in generatedMethods: funcName = access + funcName + name functionCode = propData[funcName] node = compileString(functionCode) commentAttributes = comment.parseNode(node) docNode = handleFunction(node, funcName, commentAttributes, classNode) docNode.set("fromProperty", propertyName) classNode.addListChild("methods", docNode)
def handleClassDefinition(docTree, item, variant): params = item.getChild("params") className = params.children[0].get("value") if len(params.children) > 1: classMap = params.children[1] else: classMap = {} commentAttributes = comment.parseNode(item) classNode = getClassNode(docTree, className, commentAttributes) if variant == "class": classNode.set("type", "class") type = selectNode(params, "2/keyvalue[@key='type']/value/constant/@value") if type == "singleton": classNode.set("isSingleton", True) elif type == "abstract": classNode.set("isAbstract", True) else: classNode.set("type", variant) handleDeprecated(classNode, commentAttributes) handleAccess(classNode, commentAttributes) handleAppearance(item, classNode, className, commentAttributes) try: children = classMap.children except AttributeError: return for keyvalueItem in children: if keyvalueItem.type != "keyvalue": continue key = keyvalueItem.get("key") valueItem = keyvalueItem.getChild("value").getFirstChild() # print "KEY: %s = %s" % (key, valueItem.type) if key == "extend": if variant == "class": handleClassExtend(valueItem, classNode, docTree, className) elif variant == "interface": handleInterfaceExtend(valueItem, classNode, docTree, className) elif key == "include": handleMixins(valueItem, classNode, docTree, className) elif key == "implement": handleInterfaces(valueItem, classNode, docTree) elif key == "construct": handleConstructor(valueItem, classNode) elif key == "statics": handleStatics(valueItem, classNode) elif key == "properties": handleProperties(valueItem, classNode) elif key == "members": handleMembers(valueItem, classNode) elif key == "events": handleEvents(valueItem, classNode) handleSingleton(classNode, docTree) if not classNode.hasChild("desc"): addError(classNode, "Class documentation is missing.", item)