diff options
Diffstat (limited to 'src/qml/qml/v4/v4classgen')
-rwxr-xr-x | src/qml/qml/v4/v4classgen | 315 |
1 files changed, 0 insertions, 315 deletions
diff --git a/src/qml/qml/v4/v4classgen b/src/qml/qml/v4/v4classgen deleted file mode 100755 index 82d6dbf7f0..0000000000 --- a/src/qml/qml/v4/v4classgen +++ /dev/null @@ -1,315 +0,0 @@ -#!/usr/bin/python - -import re, sys, os - -class ParsedMethod(): - def __init__(self, name, methodPrefix, static): - self.name = name - self.methodPrefix = methodPrefix - self.options = {} - self.static = static - - def isClassMethod(self): - return self.static - - def isGetter(self): - return self.name.startswith("get_") - - def isSetter(self): - return self.name.startswith("set_") - - def isAccessor(self): - return self.isGetter() or self.isSetter() - - def nameWithoutGetterSetterPrefix(self): - return self.name[4:] - - def fullMethodName(self): - return self.methodPrefix + "_" + self.name - - def generateBinding(self, out, objectPrefix = ""): - length = 0 - - methodName = self.methodPrefix + "_" + self.name - if not self.isClassMethod(): - methodName = "wrap_" + methodName - - if "argc" in self.options: - length = self.options["argc"] - out.write(" %sdefineDefaultProperty(engine, QStringLiteral(\"%s\"), %s, %s);\n" % (objectPrefix, self.name, methodName, length)) - if "alias" in self.options: - out.write(" %sdefineDefaultProperty(engine, QStringLiteral(\"%s\"), %s, %s);\n" % (objectPrefix, self.options["alias"], methodName, length)) - - def generateMemberFunctionWrapper(self, out, parsedClass): - out.write("static QV4::Value wrap_%s_%s(QV4::SimpleCallContext *ctx)\n" % (self.methodPrefix, self.name)) - out.write("{\n") - out.write(" QV4::Object *thatObject = ctx->thisObject.asObject();\n") - out.write(" if (!thatObject)\n") - out.write(" ctx->throwTypeError();\n") - out.write(" %s *o = thatObject->as%s();\n" % (parsedClass.name, parsedClass.managedTypeName())) - out.write(" if (!o)\n") - out.write(" ctx->throwTypeError();\n") - out.write(" return o->%s_%s(ctx);\n" % (self.methodPrefix, self.name)) - out.write("}\n") - out.write("\n") - -class ParsedClass(): - def __init__(self, name): - self.name = name - self.options = {} - self.methods = {} - self.ctor_methods = {} - self.accessors = {} - - def needsConstructor(self): - return len(self.ctor_methods) > 0 - - def managedTypeName(self): - if "managedTypeName" in self.options: - return self.options["managedTypeName"] - return self.name - - def option(self, name): - if name in self.options: - return self.options[name] - return None - -class Accessor(): - def __init__(self, name): - self.name = name - self.getter = None - self.setter = None - - def generateBinding(self, out, parsedClass, obj): - managedType = "type" - if len(obj) > 0: - managedType = obj + "internalType()" - - getter = "0" - if self.getter: - getter = "%s::%s" % (parsedClass.name, self.getter.fullMethodName()) - setter = "0" - if self.setter: - setter = "%s::%s" % (parsedClass.name, self.setter.fullMethodName()) - - out.write(" %sdefineAccessorProperty(engine, QStringLiteral(\"%s\"), %s, %s);\n" % (obj, self.name, getter, setter)) - -def parseOptions(options): - options = options.split(" ") - result = {} - for opt in [options[i : i + 2] for i in range(0, len(options), 2)]: - result[opt[0]] = opt[1] - return result - -def parseMethod(line, match, methodPrefix): - annotatePattern = re.compile(r".*QV4_ANNOTATE\((?P<Options>.+)\).*") - argcPattern = re.compile(r".*QV4_ARGC\((?P<count>\d+)\).*") - - method = ParsedMethod(match.group("MethodName"), methodPrefix, line.find("static") == 0) - - annotateMatch = annotatePattern.match(line) - if annotateMatch: - method.options = parseOptions(annotateMatch.group("Options")) - - argcMatch = argcPattern.match(line) - if argcMatch: - method.options["argc"] = argcMatch.group("count") - - return method - -def parse(lines): - classes = [] - currentClass = None - classPattern = re.compile(r".*QV4_JS_CLASS\((?P<ClassName>\w+)\).*") - annotatePattern = re.compile(r".*QV4_ANNOTATE\((?P<Options>.+)\).*") - methodPattern = re.compile(r".*\smethod_(?P<MethodName>\w+)\(.*\).*;?") - ctorMethodPattern = re.compile(r".*\sctor_method_(?P<MethodName>\w+)\(.*\).*;") - - for line in lines: - if line == "};" and currentClass != None: - classes.append(currentClass) - currentClass = None - continue - line = line.strip() - classMatch = classPattern.match(line) - if classMatch: - name = classMatch.group("ClassName") - if currentClass != None: - classes.append(currentClass) - currentClass = ParsedClass(name) - continue - - if currentClass == None: - continue - - methodMatch = methodPattern.match(line) - if methodMatch: - method = parseMethod(line, methodMatch, "method") - if method.isAccessor(): - name = method.nameWithoutGetterSetterPrefix() - acc = currentClass.accessors.setdefault(name, Accessor(name)) - if method.isSetter(): - acc.setter = method - else: - acc.getter = method - else: - currentClass.methods[method.name] = method - continue - - ctorMethodMatch = ctorMethodPattern.match(line) - if ctorMethodMatch: - method = parseMethod(line, ctorMethodMatch, "ctor_method") - currentClass.ctor_methods[method.name] = method - continue - - annotateMatch = annotatePattern.match(line) - if annotateMatch: - currentClass.options = parseOptions(annotateMatch.group("Options")) - continue - - return classes - -def generateBinding(out, parsedClass, vtableEntries): - if parsedClass.needsConstructor(): - ctorClass = parsedClass.name.replace("Prototype", "Ctor") - - out.write("class %s: public QV4::FunctionObject {\n" % ctorClass); - out.write("public:\n"); - out.write(" %s(QV4::ExecutionContext *scope)\n" % ctorClass); - out.write(" : QV4::FunctionObject(scope, scope->engine->newIdentifier(QStringLiteral(\"%s\")))\n" % ctorClass.replace("Ctor", "")); - out.write(" { vtbl = &static_vtbl; }\n"); - out.write("\n"); - out.write("protected:\n"); - out.write(" static const QV4::ManagedVTable static_vtbl;\n"); - out.write("};\n\n"); - out.write("const QV4::ManagedVTable %s::static_vtbl = {\n" % ctorClass); - - ctorOverrides = set(parsedClass.ctor_methods.keys()) - - for method in vtableEntries: - entry = "FunctionObject::" + method - if method in ctorOverrides: - entry = parsedClass.name + "::ctor_method_" + method - out.write(" " + entry + ",\n") - out.write(" \"%s\"\n" % parsedClass.name.replace("Prototype", "Ctor")); - out.write("};\n\n") - - out.write("QV4::Object *%s::newConstructor(QV4::ExecutionContext *scope)\n" % parsedClass.name) - out.write("{\n") - out.write(" return new (scope->engine->memoryManager) %s(scope);\n" % ctorClass) - out.write("}\n\n") - - for method in parsedClass.methods.values(): - if not method.isClassMethod(): - method.generateMemberFunctionWrapper(out, parsedClass) - - for method in parsedClass.ctor_methods.values(): - if not method.isClassMethod(): - method.generateMemberFunctionWrapper(out, parsedClass) - - ctorSignature = "" - if parsedClass.needsConstructor(): - ctorSignature = ", const QV4::Value &ctor" - - obj = "" - objSignature = "" - if parsedClass.option("staticInitClass") == "true": - objSignature = ", const QV4::Value &obj" - obj = "obj.objectValue()->" - - out.write("void %s::initClass(QV4::ExecutionEngine *engine%s%s)\n" % (parsedClass.name, objSignature, ctorSignature)) - out.write("{\n") - - if parsedClass.needsConstructor(): - ctor = "ctor.objectValue()->" - ctorLength = 0 - if "argc" in parsedClass.options: - ctorLength = parsedClass.options["argc"] - - out.write(" %sdefineReadonlyProperty(engine->id_prototype, QV4::Value::fromObject(this));\n" % ctor) - out.write(" %sdefineReadonlyProperty(engine->id_length, QV4::Value::fromInt32(%s));\n" % (ctor, ctorLength)) - out.write("\n") - - for method in parsedClass.ctor_methods.values(): - if method.name == "construct" or method.name == "call": - continue - method.generateBinding(out, ctor); - - out.write("\n") - out.write(" defineDefaultProperty(engine, QStringLiteral(\"constructor\"), ctor);\n"); - - out.write("\n") - - for method in parsedClass.methods.values(): - method.generateBinding(out, obj) - - for accessor in parsedClass.accessors.values(): - accessor.generateBinding(out, parsedClass, obj) - - out.write("}\n") - -def extractManagedVTableLayout(basePath): - def VTableDefintionIterator(lines): - i = 0 - while i < len(lines): - if lines[i].strip().startswith("#define DEFINE_MANAGED_VTABLE(classname)"): - break; - i = i + 1 - if i >= len(lines): - return - i = i + 1 - if not lines[i].strip().startswith("const QV4::ManagedVTable classname::static_vtbl ="): - print("Expected static_vtbl definition at line %s" % i) - return - i = i + 1 - if not lines[i].strip().startswith("{"): - print("Expected static_vtbl definition at line %s" % i) - return - i = i + 1 - while i < len(lines): - line = lines[i].strip() - if "#classname" in line: - break - yield line.split(",")[0] - i = i + 1 - return - - qv4managedHeader = basePath + "/qv4managed_p.h" - fields = [] - try: - header = open(qv4managedHeader, "r") - it = VTableDefintionIterator(header.read().splitlines()) - for entry in it: - fields.append(entry) - header.close() - except IOError: - print("Could not open qv4managed_p.h at %s" % qv4managedHeader) - sys.exit(1) - return fields - -if len(sys.argv) != 3 and len(sys.argv) != 2: - print("Usage: v4classgen input-file [output-file]\n") - sys.exit(1) - -vtableEntries = extractManagedVTableLayout(os.path.dirname(__file__)) -if len(vtableEntries) == 0: - print("Could not parse vtable layout from qv4managed_p.h") - sys.exit(1) - -f = open(sys.argv[1]) - -out = sys.stdout -if len(sys.argv) == 3: - out = open(sys.argv[2], 'w') - -lines = f.read().splitlines() -classes = parse(lines) -f.close() - -out.write("/* Generated file, do not edit */\n") - -for parsedClass in classes: - out.write("\n") - generateBinding(out, parsedClass, vtableEntries) - -out.close() |