void DeclarationBuilder::visitFuncDeclaration(IFunctionDeclaration *node)
{
	TypeBuilder::visitFuncDeclaration(node);
	DUChainWriteLocker lock;
	if(inClassScope)
	{
		ClassFunctionDeclaration *newMethod = openDefinition<ClassFunctionDeclaration>(node->getName(), node);
		if(node->getComment())
			newMethod->setComment(QString::fromUtf8(node->getComment()));
		newMethod->setKind(KDevelop::Declaration::Type);
		lock.unlock();
		ContextBuilder::visitFuncDeclaration(node);
		lock.lock();
		closeDeclaration();
		newMethod->setInternalContext(lastContext());
		newMethod->setType(currentFunctionType);
	}
	else
	{
		FunctionDeclaration *newMethod = openDefinition<FunctionDeclaration>(node->getName(), node);
		if(node->getComment())
			newMethod->setComment(QString::fromUtf8(node->getComment()));
		newMethod->setKind(KDevelop::Declaration::Type);
		lock.unlock();
		ContextBuilder::visitFuncDeclaration(node);
		lock.lock();
		closeDeclaration();
		newMethod->setInternalContext(lastContext());
		newMethod->setType(currentFunctionType);
	}
}
Esempio n. 2
0
void UsesCollector::startCollecting() {
    DUChainReadLocker lock(DUChain::lock());

    if(Declaration* decl = m_declaration.data()) {

        if(m_collectDefinitions) {
          if(FunctionDefinition* def = dynamic_cast<FunctionDefinition*>(decl)) {
          //Jump from definition to declaration
            Declaration* declaration = def->declaration();
            if(declaration)
              decl = declaration;
          }
        }

        ///Collect all overloads into "decls"
        QList<Declaration*> decls;

        if(m_collectOverloads && decl->context()->owner() && decl->context()->type() == DUContext::Class) {
          //First find the overridden base, and then all overriders of that base.
          while(Declaration* overridden = DUChainUtils::getOverridden(decl))
            decl = overridden;
          uint maxAllowedSteps = 10000;
          decls += DUChainUtils::getOverriders( decl->context()->owner(), decl, maxAllowedSteps );
          if(maxAllowedSteps == 10000) {
            ///@todo Fail!
          }
        }

        decls << decl;

        ///Collect all "parsed versions" or forward-declarations etc. here, into allDeclarations
        QSet<IndexedDeclaration> allDeclarations;

        foreach(Declaration* overload, decls) {
          m_declarations = DUChainUtils::collectAllVersions(overload);
          foreach(const IndexedDeclaration &d, m_declarations) {
            if(!d.data() || d.data()->id() != overload->id())
              continue;
            allDeclarations.insert(d);

            if(m_collectConstructors && d.data() && d.data()->internalContext() && d.data()->internalContext()->type() == DUContext::Class) {
              QList<Declaration*> constructors = d.data()->internalContext()->findLocalDeclarations(d.data()->identifier(), CursorInRevision::invalid(), nullptr, AbstractType::Ptr(), DUContext::OnlyFunctions);
              foreach(Declaration* constructor, constructors) {
                ClassFunctionDeclaration* classFun = dynamic_cast<ClassFunctionDeclaration*>(constructor);
                if(classFun && classFun->isConstructor())
                  allDeclarations.insert(IndexedDeclaration(constructor));
              }

              Identifier destructorId = destructorForName(d.data()->identifier());

              QList<Declaration*> destructors = d.data()->internalContext()->findLocalDeclarations(destructorId, CursorInRevision::invalid(), nullptr, AbstractType::Ptr(), DUContext::OnlyFunctions);
              foreach(Declaration* destructor, destructors) {
                ClassFunctionDeclaration* classFun = dynamic_cast<ClassFunctionDeclaration*>(destructor);
                if(classFun && classFun->isDestructor())
                  allDeclarations.insert(IndexedDeclaration(destructor));
              }
            }
void DeclarationBuilder::visitDestructor(IDestructor *node)
{
	TypeBuilder::visitDestructor(node);
	DUChainWriteLocker lock;
	ClassFunctionDeclaration *newMethod = openDefinition<ClassFunctionDeclaration>(QualifiedIdentifier("~this"), editorFindRange(node, node));
	if(node->getComment())
		newMethod->setComment(QString::fromUtf8(node->getComment()));
	newMethod->setKind(KDevelop::Declaration::Type);
	lock.unlock();
	ContextBuilder::visitDestructor(node);
	lock.lock();
	closeDeclaration();
	newMethod->setInternalContext(lastContext());
	newMethod->setType(currentFunctionType);
}
Esempio n. 4
0
DeclarationPointer getDeclarationOrSignal(const QualifiedIdentifier& id, const DUContext* context, bool searchInParent)
{
    QString identifier = id.last().toString();

    if (identifier.startsWith(QLatin1String("on")) && identifier.size() > 2) {
        // The use may have typed the name of a QML slot (onFoo), try to get
        // the declaration of its corresponding signal (foo)
        identifier = identifier.at(2).toLower() + identifier.mid(3);
        DeclarationPointer decl = getDeclaration(QualifiedIdentifier(identifier), context, searchInParent);

        if (decl) {
            ClassFunctionDeclaration* classFuncDecl = dynamic_cast<ClassFunctionDeclaration *>(decl.data());

            if (classFuncDecl && classFuncDecl->isSignal()) {
                // Removing "on" has given the identifier of a QML signal, return
                // it instead of the name of its slot
                return decl;
            }
        }
    }

    // No signal found, fall back to normal behavior
    return getDeclaration(id, context, searchInParent);
}
QVariant NormalDeclarationCompletionItem::data(const QModelIndex& index, int role, const KDevelop::CodeCompletionModel* model) const
{
  DUChainReadLocker lock(DUChain::lock(), 500);
  if(!lock.locked()) {
    kDebug(9007) << "Failed to lock the du-chain in time";
    return QVariant();
  }

  switch (role) {
    case Qt::DisplayRole:
      if (index.column() == CodeCompletionModel::Name) {
        return declarationName();
      } else if(index.column() == CodeCompletionModel::Postfix) {
          if (FunctionType::Ptr functionType = m_declaration->type<FunctionType>()) {
            // Retrieve const/volatile string
            return functionType->AbstractType::toString();
          }
      } else if(index.column() == CodeCompletionModel::Prefix) {
          if (m_declaration->abstractType()) {
            if(EnumeratorType::Ptr enumerator = m_declaration->type<EnumeratorType>()) {
              if(m_declaration->context()->owner() && m_declaration->context()->owner()->abstractType()) {
                if(!m_declaration->context()->owner()->identifier().isEmpty())
                  return shortenedTypeString(DeclarationPointer(m_declaration->context()->owner()), desiredTypeLength);
                else
                  return "enum";
              }
            }
            if (FunctionType::Ptr functionType = m_declaration->type<FunctionType>()) {
              ClassFunctionDeclaration* funDecl = dynamic_cast<ClassFunctionDeclaration*>(m_declaration.data());

              if (functionType->returnType()) {
                QString ret = shortenedTypeString(m_declaration, desiredTypeLength);
                if(shortenArgumentHintReturnValues && argumentHintDepth() && ret.length() > maximumArgumentHintReturnValueLength)
                  return QString("...");
                else
                  return ret;
              }else if(argumentHintDepth()) {
                return QString();//Don't show useless prefixes in the argument-hints
              }else if(funDecl && funDecl->isConstructor() )
                return "<constructor>";
              else if(funDecl && funDecl->isDestructor() )
                return "<destructor>";
              else
                return "<incomplete type>";

            } else {
              return shortenedTypeString(m_declaration, desiredTypeLength);
            }
          } else {
            return "<incomplete type>";
          }
        }
      break;
    case CodeCompletionModel::BestMatchesCount:
      return QVariant(normalBestMatchesCount);
    break;
    case CodeCompletionModel::IsExpandable:
      return QVariant(createsExpandingWidget());
    case CodeCompletionModel::ExpandingWidget: {
      QWidget* nav = createExpandingWidget(model);
      Q_ASSERT(nav);
      model->addNavigationWidget(this, nav);

      QVariant v;
      v.setValue<QWidget*>(nav);
      return v;
    }
    case CodeCompletionModel::ScopeIndex:
      return static_cast<int>(reinterpret_cast<long>(m_declaration->context()));

    case CodeCompletionModel::CompletionRole:
      return (int)completionProperties();
    case Qt::DecorationRole:
     {
      if( index.column() == CodeCompletionModel::Icon ) {
        CodeCompletionModel::CompletionProperties p = completionProperties();
        lock.unlock();
        return DUChainUtils::iconForProperties(p);
      }
      break;
    }

  }
  return QVariant();
}