QWidget* DUChainItemData::expandingWidget() const { DUChainReadLocker lock;; Declaration* decl = dynamic_cast<KDevelop::Declaration*>(m_item.m_item.data()); if( !decl || !decl->context() ) { return 0; } return decl->context()->createNavigationWidget( decl, decl->topContext(), m_item.m_project.isEmpty() ? QString() : ("<small><small>" + i18n("Project %1", m_item.m_project) + "<br></small></small>") ); }
void ADLHelper::addArgumentType(const AbstractType::Ptr typePtr) { if(m_alreadyProcessed.contains(typePtr.data())) return; if (typePtr) { #ifdef DEBUG_ADL qCDebug(CPPDUCHAIN) << " added argument type " << typePtr->toString() << " to ADL lookup"; #endif // the enumeration and enumerator types are not part of the TypeVisitor interface switch (typePtr->whichType()) { case AbstractType::TypeEnumeration: { EnumerationType* specificType = fastCast<EnumerationType*>(typePtr.data()); if (specificType) { Declaration * enumDecl = specificType->declaration(m_topContext.data()); addDeclarationScopeIdentifier(enumDecl); } break; } case AbstractType::TypeEnumerator: { if (m_templateArgsDepth == 0) { EnumeratorType* specificType = fastCast<EnumeratorType*>(typePtr.data()); if (specificType) { // use the enumeration context for the enumerator value declaration to find out the namespace Declaration * enumeratorDecl = specificType->declaration(m_topContext.data()); if (enumeratorDecl) { DUContext * enumContext = enumeratorDecl->context(); if (enumContext) { addAssociatedNamespace(enumContext->scopeIdentifier(false)); } } } } break; } default: typePtr->accept(&m_typeVisitor); } } m_alreadyProcessed.insert(typePtr.data()); }
void ADLTypeVisitor::endVisit(const FunctionType * /*type*/) { // return type and argument types are handled by FunctionType::accept0 // here we process the namespace of the function name (or containing class), if any /* at the bottom of 3.4.2.2 we find the following: In addition, if the argument is the name or address of a set of overloaded functions and/or function tem- plates, its associated classes and namespaces are the union of those associated with each of the members of the set: the namespace in which the function or function template is defined and the classes and namespaces associated with its (non-dependent) parameter types and return type. */ if (m_helper.m_possibleFunctionName.data() && m_helper.m_possibleFunctionName.data()->isFunctionDeclaration()) { Declaration * declaration = m_helper.m_possibleFunctionName.data(); #ifdef DEBUG_ADL qCDebug(CPPDUCHAIN) << " function name = " << declaration->toString() << " ; identifier = " << declaration->qualifiedIdentifier().toString(); #endif // start going towards the global scope until we match an interesting name // note that calling addDeclarationScopeIdentifier does not work because for some reason // for function names DUContext::scopeIdentifier returns the function name instead of the // name of the function's scope DUContext* context = declaration->context(); while (context) { if (Declaration* decl = context->owner()) { if (context->type() == DUContext::Namespace) { m_helper.addAssociatedNamespace(decl->qualifiedIdentifier()); break; } else if (context->type() == DUContext::Class) { m_helper.addAssociatedClass(decl); break; } } context = context->parentContext(); } } }
void CorrectionFileGenerator::addHint(const QString &typeCode, const QStringList &modules, Declaration *forDeclaration, CorrectionFileGenerator::HintType hintType) { if ( ! forDeclaration || ! forDeclaration->context() ) { qCWarning(KDEV_PYTHON_CODEGEN) << "Declaration does not have context!" << (forDeclaration ? forDeclaration->toString() : ""); return; } DUContext* context = forDeclaration->context(); if ( context->type() == DUContext::Function ) { auto otherImporters = context->importers(); if ( otherImporters.isEmpty() ) { return; } context = otherImporters.first(); } // We're in a class if the context of the declaration is a Class or if its // parent context is a class. This is because a function body has a context // of type Other. bool inClass = context->type() == DUContext::Class || (context->parentContext() && context->parentContext()->type() == DUContext::Class); // If the declaration is part of the function's arguments or it's parent // context is one of a function. bool inFunction = context->type() == DUContext::Function || (context->owner() && context->owner()->abstractType()->whichType() == AbstractType::TypeFunction); qCDebug(KDEV_PYTHON_CODEGEN) << "Are we in a class: " << inClass; qCDebug(KDEV_PYTHON_CODEGEN) << "Are we in a function: " << inFunction; QString enclosingClassIdentifier, enclosingFunctionIdentifier; if ( context->owner() ) { if ( inClass && inFunction ) { Declaration *functionDeclaration = context->owner(); enclosingClassIdentifier = functionDeclaration->context()->owner()->identifier().identifier().str(); enclosingFunctionIdentifier = functionDeclaration->identifier().identifier().str(); } else if ( inClass ) { enclosingClassIdentifier = context->owner()->identifier().identifier().str(); } else if ( inFunction ) { enclosingFunctionIdentifier = context->owner()->identifier().identifier().str(); } } qCDebug(KDEV_PYTHON_CODEGEN) << "Enclosing class: " << enclosingClassIdentifier; qCDebug(KDEV_PYTHON_CODEGEN) << "Enclosing function: " << enclosingFunctionIdentifier; QString declarationIdentifier = forDeclaration->identifier().identifier().str(); bool foundClassDeclaration = false; bool foundFunctionDeclaration = false; QString functionIdentifier; if ( hintType == FunctionReturnHint ) { functionIdentifier = declarationIdentifier; } else if ( hintType == LocalVariableHint ) { functionIdentifier = enclosingFunctionIdentifier; } int line = findStructureFor(enclosingClassIdentifier, functionIdentifier); if ( line == -1 ) { line = findStructureFor(enclosingClassIdentifier, QString()); } else if ( inFunction || hintType == FunctionReturnHint ) { foundFunctionDeclaration = true; } if ( line == -1 ) { line = findStructureFor(QString(), QString()); } else if ( inClass ) { foundClassDeclaration = true; } qCDebug(KDEV_PYTHON_CODEGEN) << "Found class declaration: " << foundClassDeclaration << enclosingClassIdentifier; qCDebug(KDEV_PYTHON_CODEGEN) << "Found function declaration: " << foundFunctionDeclaration << functionIdentifier; qCDebug(KDEV_PYTHON_CODEGEN) << "Line: " << line; int indentsForNextStatement = m_fileIndents->indentForLine(line); if ( foundClassDeclaration ) { indentsForNextStatement += DEFAULT_INDENT_LEVEL; } QStringList newCode; if ( inClass ) { if ( ! foundClassDeclaration ) { QString classDeclaration = createStructurePart(enclosingClassIdentifier, ClassType); classDeclaration.prepend(QString(indentsForNextStatement, ' ')); newCode.append(classDeclaration); indentsForNextStatement += DEFAULT_INDENT_LEVEL; } else { line++; } } if ( inFunction || hintType == FunctionReturnHint ) { if ( ! foundFunctionDeclaration ) { QString functionDeclaration; if ( inClass ) { functionDeclaration = createStructurePart(functionIdentifier, MemberFunctionType); } else { functionDeclaration = createStructurePart(functionIdentifier, FunctionType); } functionDeclaration.prepend(QString(indentsForNextStatement, ' ')); newCode.append(functionDeclaration); indentsForNextStatement += DEFAULT_INDENT_LEVEL; } else { line++; } } if ( foundFunctionDeclaration && ! foundClassDeclaration ) { indentsForNextStatement += DEFAULT_INDENT_LEVEL; } QString hintCode; if ( hintType == FunctionReturnHint ) { hintCode = "returns = " + typeCode; } else if ( hintType == LocalVariableHint ) { hintCode = "l_" + declarationIdentifier + " = " + typeCode; } qCDebug(KDEV_PYTHON_CODEGEN) << "Hint code: " << hintCode; hintCode.prepend(QString(indentsForNextStatement, ' ')); newCode.append(hintCode); for ( int i = 0; i < newCode.length(); i++ ) { m_code.insert(line + i, newCode.at(i)); } // We safely insert any import declaration at the top foreach ( const QString &moduleName, modules ) { bool importExists = false; foreach (const QString &line, m_code) { if ( ! line.startsWith("import") && ! line.startsWith("from") && ! line.isEmpty() ) { break; } // In both import ... and from ... import ..., the second part is what we want if ( line.section(' ', 1, 1, QString::SectionSkipEmpty) == moduleName.trimmed() ) { importExists = true; } } if ( ! importExists ) { m_code.prepend("import " + moduleName.trimmed()); } }