Alien-SmokeQt
view release on metacpan or search on metacpan
generator/generatorvisitor.cpp view on Meta::CPAN
do {
nspace.push_back(name);
QString n = nspace.join("::");
returnOnExistence(n);
nspace.pop_back();
if (!nspace.isEmpty())
nspace.pop_back();
} while (!nspace.isEmpty());
// check for nested classes
for (int i = klass.count() - 1; i >= 0; i--) {
QString _name = klass[i]->toString() + "::" + name;
returnOnExistence(_name);
BasicTypeDeclaration* decl = resolveTypeInSuperClasses(klass[i], name);
if (decl)
return decl;
}
// maybe it's just 'there'
returnOnExistence(name);
// check for the name in any of the namespaces included by 'using namespace'
foreach (const QStringList& list, usingNamespaces) {
foreach (const QString& string, list) {
QString cname = string + "::" + name;
returnOnExistence(cname);
}
}
QStringList parts = name.split("::");
if (parts.count() > 1) {
// try to resolve the first part - if that works simply append the last part.
BasicTypeDeclaration* decl = resolveType(parts.takeFirst());
if (!decl)
return 0;
parts.prepend(decl->toString());
name = parts.join("::");
returnOnExistence(name);
} else {
// maybe it's an enum value (as used for template args in phonon)
// look through all the enums of the parent classes
if (!klass.isEmpty()) {
const Class* clazz = klass.top();
while (clazz) {
foreach (BasicTypeDeclaration* decl, klass.top()->children()) {
Enum* e = 0;
if (!(e = dynamic_cast<Enum*>(decl)))
continue;
foreach (const EnumMember& member, e->members()) {
if (member.name() == name) {
name.prepend(klass.top()->toString() + "::");
return 0;
}
}
}
clazz = clazz->parent();
}
}
// look through all global enums in our namespace
QStringList nspace = this->nspace;
do {
QString n = nspace.join("::");
foreach (const Enum& e, enums.values()) {
if (e.parent())
continue;
if (e.nameSpace() == n) {
foreach (const EnumMember& member, e.members()) {
if (member.name() == name) {
name.prepend(n + "::");
return 0;
}
}
}
}
if (!nspace.isEmpty())
nspace.pop_back();
} while (!nspace.isEmpty());
}
return 0;
}
QString GeneratorVisitor::resolveEnumMember(const QString& name)
{
QString parent, member;
int idx = -1;
if ((idx = name.lastIndexOf("::")) != -1) {
parent = name.mid(0, idx);
member = name.mid(idx + 2);
} else {
member = name;
}
return resolveEnumMember(parent, member);
}
// TODO: This doesn't look for the enum in superclasses and parent classes yet - but it suffices for the moment.
QString GeneratorVisitor::resolveEnumMember(const QString& parent, const QString& name)
{
// is 'parent' a know class?
if (!parent.isEmpty()) {
BasicTypeDeclaration* decl = resolveType(parent);
if (decl)
return decl->toString() + "::" + name;
}
// doesn't seem to be a class, so it's probably a part of a namespace name
QStringList nspace = this->nspace;
do {
QString n = nspace.join("::");
if (!n.isEmpty() && !parent.isEmpty()) n += "::";
n += parent;
foreach (const Enum& e, enums.values()) {
if (e.parent())
continue;
if (e.nameSpace() == n) {
foreach (const EnumMember& member, e.members()) {
generator/generatorvisitor.cpp view on Meta::CPAN
returnType = Type::registerType(t);
} else if (isDestructor) {
// destructors don't have a return type.. so return void
returnType = const_cast<Type*>(Type::Void);
} else if (nc->isCastOperator()) {
returnType = Type::registerType(nc->castType());
}
currentMethod = Method(klass.top(), declName, returnType, access.top());
currentMethod.setIsConstructor(isConstructor);
currentMethod.setIsDestructor(isDestructor);
currentMethod.setIsSignal(inSignals.top());
currentMethod.setIsSlot(inSlots.top());
// build parameter list
inMethod = true;
visit(node->parameter_declaration_clause);
inMethod = false;
QPair<bool, bool> cv = parseCv(node->fun_cv);
// const & volatile modifiers
currentMethod.setIsConst(cv.first);
if (isVirtual) currentMethod.setFlag(Method::Virtual);
if (hasInitializer) currentMethod.setFlag(Method::PureVirtual);
if (isStatic) currentMethod.setFlag(Method::Static);
if (isExplicit) currentMethod.setFlag(Method::Explicit);
// the class already contains the method (probably imported by a 'using' statement)
if (klass.top()->methods().contains(currentMethod)) {
return;
}
// Q_PROPERTY accessor?
if (ParserOptions::qtMode) {
foreach (const QProperty& prop, q_properties.top()) {
if ( (currentMethod.parameters().count() == 0 && prop.read == currentMethod.name() && currentMethod.type()->toString().endsWith(prop.type)
&& (currentMethod.type()->pointerDepth() == 1) == prop.isPtr) // READ accessor?
|| (currentMethod.parameters().count() == 1 && prop.write == currentMethod.name()
&& currentMethod.parameters()[0].type()->toString().remove(QRegExp("^const ")).remove(QRegExp("\\&$")).endsWith(prop.type)
&& (currentMethod.parameters()[0].type()->pointerDepth() == 1) == prop.isPtr)) // or WRITE accessor?
{
currentMethod.setIsQPropertyAccessor(true);
}
}
}
if (node->exception_spec) {
currentMethod.setHasExceptionSpec(true);
if (node->exception_spec->type_ids) {
const ListNode<TypeIdAST*>* it = node->exception_spec->type_ids->toFront(), *end = it;
do {
tc->run(it->element->type_specifier, it->element->declarator);
currentMethod.appendExceptionType(tc->type());
it = it->next;
} while (it != end);
}
}
klass.top()->appendMethod(currentMethod);
return;
}
// global function
if (node->parameter_declaration_clause && !inMethod && !inClass) {
if (!declName.contains("::")) {
Type* returnType = currentTypeRef;
currentFunction = Function(declName, nspace.join("::"), returnType);
currentFunction.setFileName(m_header);
// build parameter list
inMethod = true;
visit(node->parameter_declaration_clause);
inMethod = false;
QString name = currentFunction.toString();
if (!functions.contains(name)) {
functions[name] = currentFunction;
}
}
return;
}
// field
if (!inMethod && !klass.isEmpty() && inClass) {
Field field = Field(klass.top(), declName, currentTypeRef, access.top());
if (isStatic) field.setFlag(Field::Static);
klass.top()->appendField(field);
return;
} else if (!inMethod && !inClass) {
// global variable
if (!globals.contains(declName)) {
GlobalVar var = GlobalVar(declName, nspace.join("::"), currentTypeRef);
var.setFileName(m_header);
globals[var.name()] = var;
}
return;
}
}
void GeneratorVisitor::visitElaboratedTypeSpecifier(ElaboratedTypeSpecifierAST* node)
{
tc->run(node);
createType = true;
DefaultVisitor::visitElaboratedTypeSpecifier(node);
}
void GeneratorVisitor::visitEnumSpecifier(EnumSpecifierAST* node)
{
nc->run(node->name);
Class* parent = klass.isEmpty() ? 0 : klass.top();
currentEnum = Enum(nc->name(), nspace.join("::"), parent);
Access a = (access.isEmpty() ? Access_public : access.top());
currentEnum.setAccess(a);
currentEnum.setFileName(m_header);
QHash<QString, Enum>::iterator it = enums.insert(currentEnum.toString(), currentEnum);
currentEnumRef = &it.value();
visitNodes(this, node->enumerators);
if (parent)
parent->appendChild(currentEnumRef);
}
void GeneratorVisitor::visitEnumerator(EnumeratorAST* node)
{
currentEnumRef->appendMember(EnumMember(currentEnumRef, token(node->id).symbolString(), QString()));
// DefaultVisitor::visitEnumerator(node);
}
void GeneratorVisitor::visitFunctionDefinition(FunctionDefinitionAST* node)
{
visit(node->type_specifier);
if (node->function_specifiers) {
const ListNode<std::size_t> *it = node->function_specifiers->toFront(), *end = it;
do {
if (it->element && m_session->token_stream->kind(it->element) == Token_virtual) {
// found virtual token
isVirtual = true;
} else if (it->element && m_session->token_stream->kind(it->element) == Token_explicit) {
isExplicit = true;
}
it = it->next;
} while (end != it);
}
if (node->storage_specifiers) {
const ListNode<std::size_t> *it = node->storage_specifiers->toFront(), *end = it;
do {
if (it->element && m_session->token_stream->kind(it->element) == Token_static) {
isStatic = true;
} else if (it->element && m_session->token_stream->kind(it->element) == Token_friend) {
// we're not interested in who's the friend of whom ;)
return;
}
it = it->next;
} while (end != it);
}
( run in 0.765 second using v1.01-cache-2.11-cpan-13bb782fe5a )