예제 #1
0
파일: context.cpp 프로젝트: KDE/kdev-ruby
QList<CompletionTreeItemPointer> CodeCompletionContext::getCompletionItemsForOneType(AbstractType::Ptr type, bool scoped)
{
    QList<CompletionTreeItemPointer> list;
    QList<DeclarationPair> decls;
    StructureType::Ptr sType = StructureType::Ptr::dynamicCast(type);

    {
        DUChainReadLocker lock;
        if (!sType || !sType->internalContext(m_duContext->topContext())) {
            return QList<CompletionTreeItemPointer>();
        }
        DUContext *current = sType->internalContext(m_duContext->topContext());
        decls = current->allDeclarations(CursorInRevision::invalid(), m_duContext->topContext(), false);
    }

    foreach (DeclarationPair d, decls) {
        MethodDeclaration *md = dynamic_cast<MethodDeclaration *>(d.first);
        if (md && md->accessPolicy() == Declaration::Public) {
            if (!scoped || (scoped && md->isClassMethod())) {

                ADD_NORMAL(d.first, d.second);
            }
        } else if (scoped && dynamic_cast<ModuleDeclaration *>(d.first)) {
            ADD_NORMAL(d.first, d.second);
        }
    }
예제 #2
0
Declaration * DUChainTestBase::getBuiltinDeclaration(const QString &name, TopDUContext *top, DUContext *ctx)
{
    QStringList list = name.split("#");
    DUContext *context = (ctx) ? ctx : top->childContexts().first();
    AbstractType::Ptr type = getBuiltinsType(list.first(), context);
    StructureType::Ptr sType = StructureType::Ptr::dynamicCast(type);
    Declaration *d = sType->declaration(top);

    QualifiedIdentifier id(list.first() + "::" + list.last());
    QList<Declaration *> decls = d->internalContext()->findDeclarations(id);
    return (decls.isEmpty()) ? nullptr : decls.last();
}
예제 #3
0
void ADLHelper::addBaseClasses(Declaration* declaration)
{
    ClassDeclaration * classDecl = dynamic_cast<ClassDeclaration*>(declaration);
    if (classDecl)
    {
        int nBaseClassesCount = classDecl->baseClassesSize();
        for (int i = 0; i < nBaseClassesCount; ++i)
        {
            const BaseClassInstance baseClass = classDecl->baseClasses()[i];
            StructureType::Ptr type = baseClass.baseClass.type<StructureType>();
            if (type)
                addAssociatedClass(type->declaration(m_topContext.data()));
        }
    }
}
void ExpressionVisitor::encounter(AbstractType::Ptr type, EncounterFlags flags)
{
    if ( type )
        kDebug() << "type encountered: " << type->toString();
    else
        kDebug() << "unknown type encountered";
    if ( flags & AutomaticallyDetermineDeclaration ) {
        StructureType::Ptr t = type.cast<StructureType>();
        if ( t ) {
            encounterDeclaration(t->declaration(m_ctx->topContext()));
        }
        else {
            encounterDeclaration(0);
        }
    }
    m_lastType.push(encounterPreprocess(type, flags & MergeTypes));
}
예제 #5
0
void DeclarationBuilder::visitSingletonClass(Ast *node)
{
    ExpressionVisitor ev(currentContext(), m_editor);
    Node *aux = node->tree;

    node->tree = node->tree->r;
    ev.visitNode(node);
    if (ev.lastType()) {
        DeclarationPointer d = ev.lastDeclaration();
        if (d) {
            m_instance = false;
            if (!d->internalContext()) {
                StructureType::Ptr sType;
                UnsureType::Ptr ut = ev.lastType().cast<UnsureType>();
                if (ut && ut->typesSize() > 0) {
                    sType = ut->types()[0].type<StructureType>();
                } else {
                    sType = StructureType::Ptr::dynamicCast(ev.lastType());
                }
                if (sType) {
                    DUChainWriteLocker lock;
                    d = sType->declaration(topContext());
                    m_instance = true;
                } else {
                    d = DeclarationPointer();
                }
            }
            if (d) {
                m_classDeclarations.push(d);
                m_injected = true;
                injectContext(d->internalContext());
            }
        }
    }

    node->tree = aux;
    m_accessPolicy.push(Declaration::Public);
    AstVisitor::visitSingletonClass(node);
    m_accessPolicy.pop();
    if (m_injected) {
        closeInjectedContext();
        m_injected = false;
        m_classDeclarations.pop();
    }
}
예제 #6
0
void ExpressionVisitor::instantiateCurrentDeclaration()
{
    StructureType::Ptr type = StructureType::Ptr(new StructureType);
    DeclarationPointer decl = lastDeclaration();

    {
        DUChainReadLocker lock;
        auto funcType = QmlJS::FunctionType::Ptr::dynamicCast(decl->abstractType());

        if (funcType) {
            decl = funcType->declaration(topContext());
        }

        type->setDeclaration(decl.data());
    }

    encounter(AbstractType::Ptr::staticCast(type), decl);
}
예제 #7
0
void DeclarationBuilder::visitMethodStatement(Ast *node)
{
    RangeInRevision range = getNameRange(node);
    QualifiedIdentifier id = getIdentifier(node);
    const QByteArray comment = getComment(node);
    bool injectedContext = false;
    bool instance = true;
    Node *aux = node->tree;

    /*
     * Check if this is a singleton method. If it is so, we have to determine
     * what's the context to be injected in order to get everything straight.
     */
    // TODO: this will change with the introduction of the eigen class.
    node->tree = aux->cond;
    if (valid_children(node->tree)) {
        node->tree = node->tree->l;
        ExpressionVisitor ev(currentContext(), m_editor);
        ev.visitNode(node);
        if (ev.lastType()) {
            DeclarationPointer d = ev.lastDeclaration();
            if (d) {
                if (!d->internalContext()) {
                    DUChainWriteLocker lock;
                    StructureType::Ptr sType = StructureType::Ptr::dynamicCast(ev.lastType());
                    d = (sType) ? sType->declaration(topContext()) : nullptr;
                    instance = true;
                } else
                    instance = false;
                if (d) {
                    injectedContext = true;
                    injectContext(d->internalContext());
                    node->tree = aux->cond->r;
                    id = getIdentifier(node);
                    range = editorFindRange(node, node);
                }
            }
        }
    }
    node->tree = aux;

    // Re-open the declaration.
    bool isClassMethod = (m_injected) ? !m_instance : !instance;
    MethodDeclaration *decl = reopenDeclaration(id, range, isClassMethod);

    DUChainWriteLocker lock;
    if (!comment.isEmpty()) {
        decl->setComment(comment);
    }
    decl->clearYieldTypes();
    decl->setClassMethod(isClassMethod);

    FunctionType::Ptr type = FunctionType::Ptr(new FunctionType());
    if (currentContext()->type() == DUContext::Class) {
        decl->setAccessPolicy(currentAccessPolicy());
    }

    openType(type);
    decl->setInSymbolTable(false);
    decl->setType(type);
    decl->clearDefaultParameters();
    lock.unlock();
    DeclarationBuilderBase::visitMethodStatement(node);
    lock.lock();
    closeDeclaration();
    closeType();

    /*
     * In Ruby, a method returns the last expression if no return expression
     * has been fired. Thus, the type of the last expression has to be mixed
     * into the return type of this method.
     */
    node->tree = aux->l;
    if (node->tree && node->tree->l) {
        node->tree = get_last_expr(node->tree->l);
        if (node->tree->kind != token_return) {
            lock.unlock();
            ExpressionVisitor ev(node->context, m_editor);
            ev.visitNode(node);
            if (ev.lastType()) {
                type->setReturnType(mergeTypes(ev.lastType(), type->returnType()));
            }
            lock.lock();
        }
    }
    node->tree = aux;

    if (!type->returnType()) {
        type->setReturnType(getBuiltinsType(QStringLiteral("NilClass"), currentContext()));
    }
    decl->setType(type);
    decl->setInSymbolTable(true);

    if (injectedContext) {
        closeInjectedContext();
    }
}