Changeset View
Changeset View
Standalone View
Standalone View
duchain/expressionvisitor.cpp
Show All 25 Lines | |||||
26 | 26 | | |||
27 | #include <language/duchain/topducontext.h> | 27 | #include <language/duchain/topducontext.h> | ||
28 | #include <language/duchain/duchain.h> | 28 | #include <language/duchain/duchain.h> | ||
29 | #include <language/duchain/duchainlock.h> | 29 | #include <language/duchain/duchainlock.h> | ||
30 | #include <language/duchain/persistentsymboltable.h> | 30 | #include <language/duchain/persistentsymboltable.h> | ||
31 | #include <language/duchain/types/functiontype.h> | 31 | #include <language/duchain/types/functiontype.h> | ||
32 | #include <language/duchain/types/integraltype.h> | 32 | #include <language/duchain/types/integraltype.h> | ||
33 | #include <language/duchain/types/structuretype.h> | 33 | #include <language/duchain/types/structuretype.h> | ||
34 | #include <language/duchain/types/unsuretype.h> | ||||
34 | 35 | | |||
35 | #include "duchaindebug.h" | 36 | #include "duchaindebug.h" | ||
36 | 37 | | |||
37 | #define ifDebug(x) | 38 | #define ifDebug(x) | ||
38 | 39 | | |||
39 | using namespace KDevelop; | 40 | using namespace KDevelop; | ||
40 | 41 | | |||
41 | namespace Php | 42 | namespace Php | ||
▲ Show 20 Lines • Show All 520 Lines • ▼ Show 20 Line(s) | |||||
562 | 563 | | |||
563 | void ExpressionVisitor::visitVariableProperty(VariablePropertyAst *node) | 564 | void ExpressionVisitor::visitVariableProperty(VariablePropertyAst *node) | ||
564 | { | 565 | { | ||
565 | ifDebug(qCDebug(DUCHAIN) << "node:" << m_editor->parseSession()->symbol(node) | 566 | ifDebug(qCDebug(DUCHAIN) << "node:" << m_editor->parseSession()->symbol(node) | ||
566 | << (node->isFunctionCall != -1 ? QString("is function call") : QString("is no function call"));) | 567 | << (node->isFunctionCall != -1 ? QString("is function call") : QString("is no function call"));) | ||
567 | if (node->objectProperty && node->objectProperty->objectDimList) { | 568 | if (node->objectProperty && node->objectProperty->objectDimList) { | ||
568 | //handle $foo->bar() and $foo->baz, $foo is m_result.type() | 569 | //handle $foo->bar() and $foo->baz, $foo is m_result.type() | ||
569 | 570 | | |||
570 | if (m_result.type() && StructureType::Ptr::dynamicCast(m_result.type())) { | 571 | AbstractType::Ptr type = m_result.type(); | ||
572 | | ||||
573 | //If the variable type is unsure, try to see if it contains a StructureType. If so, use that | ||||
574 | // (since the other types do not allow accessing properties) | ||||
575 | if (type && type.cast<UnsureType>()) { | ||||
576 | UnsureType::Ptr unsureType = type.cast<UnsureType>(); | ||||
577 | int numStructureType = 0; | ||||
578 | StructureType::Ptr structureType; | ||||
579 | | ||||
580 | for (unsigned int i = 0; i<unsureType->typesSize(); ++i) { | ||||
581 | StructureType::Ptr subType = unsureType->types()[i].type<StructureType>(); | ||||
582 | if (subType) { | ||||
583 | structureType = subType; | ||||
584 | ++numStructureType; | ||||
585 | } | ||||
586 | } | ||||
587 | | ||||
588 | //Only use the found structureType if there's exactly *one* such type | ||||
589 | if (numStructureType == 1) { | ||||
590 | Q_ASSERT(structureType); | ||||
591 | type = AbstractType::Ptr(structureType); | ||||
592 | } | ||||
593 | } | ||||
594 | | ||||
595 | if (type && StructureType::Ptr::dynamicCast(type)) { | ||||
571 | DUChainReadLocker lock(DUChain::lock()); | 596 | DUChainReadLocker lock(DUChain::lock()); | ||
572 | Declaration* declaration = StructureType::Ptr::staticCast(m_result.type())->declaration(m_currentContext->topContext()); | 597 | Declaration* declaration = StructureType::Ptr::staticCast(type)->declaration(m_currentContext->topContext()); | ||
573 | if (declaration) { | 598 | if (declaration) { | ||
574 | ifDebug(qCDebug(DUCHAIN) << "parent:" << declaration->toString();) | 599 | ifDebug(qCDebug(DUCHAIN) << "parent:" << declaration->toString();) | ||
575 | DUContext* context = declaration->internalContext(); | 600 | DUContext* context = declaration->internalContext(); | ||
576 | if (!context && m_currentContext->parentContext()) { | 601 | if (!context && m_currentContext->parentContext()) { | ||
577 | if (m_currentContext->parentContext()->localScopeIdentifier() == declaration->qualifiedIdentifier()) { | 602 | if (m_currentContext->parentContext()->localScopeIdentifier() == declaration->qualifiedIdentifier()) { | ||
578 | //class is currentClass (internalContext is not yet set) | 603 | //class is currentClass (internalContext is not yet set) | ||
579 | context = m_currentContext->parentContext(); | 604 | context = m_currentContext->parentContext(); | ||
580 | } | 605 | } | ||
▲ Show 20 Lines • Show All 239 Lines • Show Last 20 Lines |