Commit e41c1ba4 authored by Aurelien Gateau's avatar Aurelien Gateau
Browse files

Split QmlClass

Introduce QmlBaseComponent and make QmlClass and a new class, QmlComponent,
inherit from it.

Split QmlClass.__str__() to avoid the multiple `if`s.
parent 571aa704
......@@ -10,23 +10,16 @@ def post_process_type(rx, text, type):
text = text[:match.start("prefix")] + text[match.end("type"):]
return text, type
class QmlClass(object):
SINGLETON_COMMENT = "/** @remark This component is a singleton */"
VERSION_COMMENT = "/** @since %s */"
def __init__(self, name, version = None):
class QmlBaseComponent(object):
def __init__(self, name):
self.name = name
self.base_name = ""
self.header_comments = []
self.footer_comments = []
self.elements = []
self.imports = []
self.comment = None
self.top_level = True
if version:
self.header_comments.append(QmlClass.VERSION_COMMENT % version)
lst = name.split(".")
self.class_name = lst[-1]
self.namespaces = lst[:-1]
def get_attributes(self):
return [x for x in self.elements if isinstance(x, QmlAttribute)]
......@@ -43,11 +36,49 @@ class QmlClass(object):
def add_element(self, element):
self.elements.append(element)
def add_header_comment(self, obj):
self.header_comments.append(obj)
def __str__(self):
lst = []
self._export_content(lst)
return "\n".join(lst)
def _export_elements(self, lst, filter=None):
for element in self.elements:
if filter and not filter(element):
continue
doc = str(element)
if doc:
lst.append(doc)
def _start_class(self, lst):
class_decl = "class " + self.class_name
if self.base_name:
class_decl += " : public " + self.base_name
class_decl += " {"
lst.append(class_decl)
lst.append("public:")
def add_footer_comment(self, obj):
self.footer_comments.append(obj)
def _end_class(self, lst):
lst.append("};")
class QmlClass(QmlBaseComponent):
SINGLETON_COMMENT = "/** @remark This component is a singleton */"
VERSION_COMMENT = "/** @since %s */"
def __init__(self, name, version=None):
QmlBaseComponent.__init__(self, name)
self.header_comments = []
self.footer_comments = []
self.imports = []
if version:
self.header_comments.append(QmlClass.VERSION_COMMENT % version)
def add_pragma(self, decl):
args = decl.split(' ', 2)[1].strip()
if args.lower() == "singleton":
self.header_comments.append(QmlClass.SINGLETON_COMMENT)
def add_import(self, decl):
module = decl.split()[1]
......@@ -56,73 +87,64 @@ class QmlClass(object):
return
self.imports.append(module)
def add_pragma(self, decl):
args = decl.split(' ', 2)[1].strip()
if args.lower() == "singleton":
self.header_comments.append(QmlClass.SINGLETON_COMMENT)
def add_header_comment(self, obj):
self.header_comments.append(obj)
def __str__(self):
name = self.name.split('.')
def add_footer_comment(self, obj):
self.footer_comments.append(obj)
lst = []
if self.top_level:
for module in self.imports:
lst.append("using namespace %s;" % module.replace('.', '::'))
if len(name) > 1:
lst.append("namespace %s {" % '::'.join(name[:-1]))
def _export_header(self, lst):
for module in self.imports:
lst.append("using namespace %s;" % module.replace('.', '::'))
if self.namespaces:
lst.append("namespace %s {" % '::'.join(self.namespaces))
lst.extend([str(x) for x in self.header_comments])
# Either the top level component, or a (grand)child component with ID.
# Do not show child objects without IDs.
show_object = True
if not self.top_level:
show_object = False
for attr in self.get_attributes():
if attr.name == "id":
if self.comment is not None:
lst.append(self.comment)
lst.append("%s %s;" % (name[-1], attr.value))
show_object = True
break
def _export_footer(self, lst):
lst.extend([str(x) for x in self.footer_comments])
# For child objects with IDs, associate the object with the top-level
# object. This avoids very deep nesting in the generated documentation.
if show_object:
class_decl = "class " + name[-1]
if len(self.base_name) > 0:
class_decl += " : public " + self.base_name
class_decl += " {"
lst.append(class_decl)
lst.append("public:")
if self.top_level:
for x in self.elements:
# Prevent empty components from adding a newline to the output.
doc = str(x)
if len(doc) > 0:
lst.append(doc)
else:
for x in self.elements:
if not isinstance(x, QmlClass):
lst.append(str(x))
if self.namespaces:
lst.append("}")
lst.append("};")
def _export_content(self, lst):
self._export_header(lst)
self._start_class(lst)
self._export_elements(lst)
self._end_class(lst)
self._export_footer(lst)
if not self.top_level:
for x in self.elements:
if isinstance(x, QmlClass):
lst.append(str(x))
lst.extend([str(x) for x in self.footer_comments])
if self.top_level and len(name) > 1:
lst.append("}")
class QmlComponent(QmlBaseComponent):
"""A component inside a QmlClass"""
def __init__(self, name):
QmlBaseComponent.__init__(self, name)
self.comment = None
if len(lst) > 0:
return "\n".join(lst)
else:
return ""
def _export_content(self, lst):
component_id = self._get_component_id()
if component_id:
if self.comment:
lst.append(self.comment)
lst.append("%s %s;" % (self.class_name, component_id))
# Export component attributes
self._start_class(lst)
self._export_elements(lst, filter=lambda x:
not isinstance(x, QmlComponent))
self._end_class(lst)
# Export child components with the top-level component. This avoids
# very deep nesting in the generated documentation.
self._export_elements(lst, filter=lambda x:
isinstance(x, QmlComponent))
def _get_component_id(self):
# Returns the id of the component, if it has one
for attr in self.get_attributes():
if attr.name == "id":
return attr.value
return None
class QmlArgument(object):
......
import doxyqml.lexer as lexer
from doxyqml.qmlclass import QmlClass, QmlArgument, QmlProperty, QmlFunction, QmlSignal, QmlAttribute
from doxyqml.qmlclass import QmlClass, QmlComponent, QmlArgument, QmlProperty, QmlFunction, QmlSignal, QmlAttribute
class QmlParserError(Exception):
......@@ -59,13 +59,12 @@ def parse_class_content(reader, cls, token, doc_token):
def parse_class_component(reader, cls, token, doc_token):
obj = QmlClass(token.value, None)
obj = QmlComponent(token.value)
parse_class_definition(reader, obj)
if doc_token is not None:
obj.comment = doc_token.value
obj.top_level = False
cls.add_element(obj)
......
......@@ -14,7 +14,6 @@ public:
Item childItem;
class Item {
public:
/** An attribute. */
var componentAttribute;
/** Another attribute. */
......@@ -32,12 +31,10 @@ string itemFunction(string str);
Item childItem2;
class Item {
public:
};
ShowChildComponent customComponentChildItem;
class ShowChildComponent {
public:
/** An attribute. */
var componentAttribute;
/** Another attribute. */
......@@ -49,14 +46,12 @@ var component.attribute;
*/
string showFunction(string str);
};
/**
* A grandchild with an ID.
*/
ShowChildComponent showCustomComponentChildItem;
class ShowChildComponent {
public:
/** An attribute. */
var componentAttribute;
/** Another attribute. */
......@@ -74,7 +69,6 @@ string showFunction(string str);
SplitView aSplitView;
class SplitView {
public:
var Layout.fillHeight;
var Layout.fillWidth;
};
......@@ -84,6 +78,5 @@ var Layout.fillWidth;
Rectangle aRectangle;
class Rectangle {
public:
};
};
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment