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); } }
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(); }
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)); }
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(); } }
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); }
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(); } }