| 456 | } |
| 457 | |
| 458 | static QList<Declaration*> inheritersInternal(const Declaration* decl, uint& maxAllowedSteps, bool collectVersions) |
| 459 | { |
| 460 | QList<Declaration*> ret; |
| 461 | |
| 462 | if(!dynamic_cast<const ClassDeclaration*>(decl)) |
| 463 | return ret; |
| 464 | |
| 465 | if(maxAllowedSteps == 0) |
| 466 | return ret; |
| 467 | |
| 468 | if(decl->internalContext() && decl->internalContext()->type() == DUContext::Class) { |
| 469 | const auto indexedImporters = decl->internalContext()->indexedImporters(); |
| 470 | for (const IndexedDUContext importer : indexedImporters) { |
| 471 | |
| 472 | DUContext* imp = importer.data(); |
| 473 | |
| 474 | if(!imp) |
| 475 | continue; |
| 476 | |
| 477 | if(imp->type() == DUContext::Class && imp->owner()) |
| 478 | ret << imp->owner(); |
| 479 | |
| 480 | --maxAllowedSteps; |
| 481 | |
| 482 | if(maxAllowedSteps == 0) |
| 483 | return ret; |
| 484 | } |
| 485 | } |
| 486 | |
| 487 | if(collectVersions && decl->inSymbolTable()) { |
| 488 | auto visitor = [&](const IndexedDeclaration& indexedDeclaration) { |
| 489 | ++maxAllowedSteps; |
| 490 | auto declaration = indexedDeclaration.data(); |
| 491 | if (declaration && declaration != decl) { |
| 492 | ret += inheritersInternal(declaration, maxAllowedSteps, false); |
| 493 | } |
| 494 | |
| 495 | if (maxAllowedSteps == 0) { |
| 496 | return PersistentSymbolTable::VisitorState::Break; |
| 497 | } else { |
| 498 | return PersistentSymbolTable::VisitorState::Continue; |
| 499 | } |
| 500 | }; |
| 501 | PersistentSymbolTable::self().visitDeclarations(decl->qualifiedIdentifier(), visitor); |
| 502 | } |
| 503 | |
| 504 | return ret; |
| 505 | } |
| 506 | |
| 507 | QList<Declaration*> DUChainUtils::inheriters(const Declaration* decl, uint& maxAllowedSteps, bool collectVersions) |
| 508 | { |
no test coverage detected