Changeset View
Changeset View
Standalone View
Standalone View
duchain/expressionvisitor.cpp
Show First 20 Lines • Show All 691 Lines • ▼ Show 20 Line(s) | 591 | { | |||
---|---|---|---|---|---|
692 | } | 692 | } | ||
693 | DefaultVisitor::visitVariableProperty(node); | 693 | DefaultVisitor::visitVariableProperty(node); | ||
694 | } | 694 | } | ||
695 | 695 | | |||
696 | void ExpressionVisitor::visitStaticMember(StaticMemberAst* node) | 696 | void ExpressionVisitor::visitStaticMember(StaticMemberAst* node) | ||
697 | { | 697 | { | ||
698 | //don't call DefaultVisitor::visitStaticMember(node); | 698 | //don't call DefaultVisitor::visitStaticMember(node); | ||
699 | //because we would end up in visitCompoundVariableWithSimpleIndirectReference | 699 | //because we would end up in visitCompoundVariableWithSimpleIndirectReference | ||
700 | if (node->staticProperty->staticProperty->variable->variable) { | 700 | if (node->staticProperty->staticProperty) { | ||
701 | if (node->staticProperty->staticProperty->variable) { | ||||
701 | DUContext* context = findClassContext(node->className); | 702 | DUContext* context = findClassContext(node->className); | ||
702 | if (context) { | 703 | if (context) { | ||
703 | useDeclaration(node->staticProperty->staticProperty->variable, context); | 704 | useDeclaration(node->staticProperty->staticProperty->variable, context); | ||
704 | } else { | 705 | } else { | ||
705 | usingDeclaration(node->className, DeclarationPointer()); | 706 | usingDeclaration(node->className, DeclarationPointer()); | ||
706 | m_result.setType(AbstractType::Ptr()); | 707 | m_result.setType(AbstractType::Ptr()); | ||
707 | } | 708 | } | ||
709 | } else if (node->staticProperty->staticProperty->expr) { | ||||
710 | const QualifiedIdentifier id = identifierForNamespace(node->className, m_editor); | ||||
711 | DeclarationPointer declaration = findDeclarationImport(ClassDeclarationType, id); | ||||
712 | usingDeclaration(node->className->namespaceNameSequence->back()->element, declaration); | ||||
713 | buildNamespaceUses(node->className, id); | ||||
714 | | ||||
715 | visitExpr(node->staticProperty->staticProperty->expr); | ||||
716 | | ||||
717 | m_result.setType(AbstractType::Ptr()); | ||||
718 | } | ||||
719 | } | ||||
720 | | ||||
708 | if (node->staticProperty->offsetItemsSequence) { | 721 | if (node->staticProperty->offsetItemsSequence) { | ||
709 | const KDevPG::ListNode< DimListItemAst* >* it = node->staticProperty->offsetItemsSequence->front(); | 722 | const KDevPG::ListNode< DimListItemAst* >* it = node->staticProperty->offsetItemsSequence->front(); | ||
710 | do { | 723 | do { | ||
711 | visitDimListItem(it->element); | 724 | visitDimListItem(it->element); | ||
712 | } while(it->hasNext() && (it = it->next)); | 725 | } while(it->hasNext() && (it = it->next)); | ||
kfunk: You already dereference `node->staticProperty->staticProperty` before in line 700; so this if… | |||||
pprkut: You're right. I restructured it to make things clearer. | |||||
713 | } | 726 | } | ||
714 | } | 727 | } | ||
715 | } | | |||
716 | 728 | | |||
717 | void ExpressionVisitor::visitClassNameReference(ClassNameReferenceAst* node) | 729 | void ExpressionVisitor::visitClassNameReference(ClassNameReferenceAst* node) | ||
718 | { | 730 | { | ||
719 | if (node->staticProperty) { | 731 | if (node->staticProperty) { | ||
720 | DUContext* context = findClassContext(node->className->identifier); | 732 | DUContext* context = findClassContext(node->className->identifier); | ||
721 | 733 | | |||
722 | if (context) { | 734 | if (context) { | ||
735 | if (node->staticProperty->staticProperty->variable) { | ||||
736 | // static properties (object::$property) | ||||
723 | useDeclaration(node->staticProperty->staticProperty->variable, context); | 737 | useDeclaration(node->staticProperty->staticProperty->variable, context); | ||
738 | } else if (node->staticProperty->staticProperty && node->staticProperty->staticProperty->expr) { | ||||
kfunk: Same here | |||||
739 | // variable static properties (object::${$property}) | ||||
740 | visitExpr(node->staticProperty->staticProperty->expr); | ||||
741 | usingDeclaration(node->className, DeclarationPointer()); | ||||
742 | } | ||||
724 | } | 743 | } | ||
725 | 744 | | |||
726 | if (node->staticProperty->offsetItemsSequence) { | 745 | if (node->staticProperty->offsetItemsSequence) { | ||
727 | const KDevPG::ListNode< DimListItemAst* >* dim_it = node->staticProperty->offsetItemsSequence->front(); | 746 | const KDevPG::ListNode< DimListItemAst* >* dim_it = node->staticProperty->offsetItemsSequence->front(); | ||
728 | do { | 747 | do { | ||
729 | visitDimListItem(dim_it->element); | 748 | visitDimListItem(dim_it->element); | ||
730 | } while(dim_it->hasNext() && (dim_it = dim_it->next)); | 749 | } while(dim_it->hasNext() && (dim_it = dim_it->next)); | ||
731 | } | 750 | } | ||
Show All 12 Lines | 758 | if (!m_result.allDeclarations().isEmpty()) { | |||
744 | const KDevPG::ListNode< ClassPropertyAst* >* it = node->propertiesSequence->front(); | 763 | const KDevPG::ListNode< ClassPropertyAst* >* it = node->propertiesSequence->front(); | ||
745 | 764 | | |||
746 | do { | 765 | do { | ||
747 | // first check for property names held in variables ($object->$property) | 766 | // first check for property names held in variables ($object->$property) | ||
748 | if (it->element->property && it->element->property->variableWithoutObjects | 767 | if (it->element->property && it->element->property->variableWithoutObjects | ||
749 | && it->element->property->variableWithoutObjects->variable->variable) { | 768 | && it->element->property->variableWithoutObjects->variable->variable) { | ||
750 | VariableIdentifierAst *varnode = it->element->property->variableWithoutObjects->variable->variable; | 769 | VariableIdentifierAst *varnode = it->element->property->variableWithoutObjects->variable->variable; | ||
751 | useDeclaration(varnode, m_currentContext); | 770 | useDeclaration(varnode, m_currentContext); | ||
771 | } else if (it->element->property && it->element->property->variableWithoutObjects | ||||
772 | && it->element->property->variableWithoutObjects->variable->expr) { | ||||
773 | // variable dynamic properties ($object->${$property}) | ||||
774 | visitExpr(it->element->property->variableWithoutObjects->variable->expr); | ||||
752 | } else if (!m_result.allDeclarations().isEmpty()) { | 775 | } else if (!m_result.allDeclarations().isEmpty()) { | ||
753 | // handle array indices after normal/static properties ($object->property[$index] // $object::$property[$index]) | 776 | // handle array indices after normal/static properties ($object->property[$index] // $object::$property[$index]) | ||
754 | if (it->element->property && it->element->property->objectDimList && it->element->property->objectDimList->offsetItemsSequence) { | 777 | if (it->element->property && it->element->property->objectDimList && it->element->property->objectDimList->offsetItemsSequence) { | ||
755 | const KDevPG::ListNode< DimListItemAst* >* dim_it = it->element->property->objectDimList->offsetItemsSequence->front(); | 778 | const KDevPG::ListNode< DimListItemAst* >* dim_it = it->element->property->objectDimList->offsetItemsSequence->front(); | ||
756 | do { | 779 | do { | ||
757 | visitDimListItem(dim_it->element); | 780 | visitDimListItem(dim_it->element); | ||
758 | } while(dim_it->hasNext() && (dim_it = dim_it->next)); | 781 | } while(dim_it->hasNext() && (dim_it = dim_it->next)); | ||
759 | } else if (it->element->staticProperty && it->element->staticProperty->offsetItemsSequence) { | 782 | } else if (it->element->staticProperty && it->element->staticProperty->offsetItemsSequence) { | ||
760 | const KDevPG::ListNode< DimListItemAst* >* dim_it = it->element->staticProperty->offsetItemsSequence->front(); | 783 | const KDevPG::ListNode< DimListItemAst* >* dim_it = it->element->staticProperty->offsetItemsSequence->front(); | ||
761 | do { | 784 | do { | ||
762 | visitDimListItem(dim_it->element); | 785 | visitDimListItem(dim_it->element); | ||
763 | } while(dim_it->hasNext() && (dim_it = dim_it->next)); | 786 | } while(dim_it->hasNext() && (dim_it = dim_it->next)); | ||
764 | } | 787 | } | ||
765 | 788 | | |||
789 | // Handle dynamic static properties first, as they don't need a class context | ||||
790 | if (it->element->staticProperty && it->element->staticProperty->staticProperty->expr) { | ||||
kfunk: And probably needs a check against `...->staticProperty->staticProperty`, too? | |||||
With the current grammer, if there's staticProperty, there's also a staticProperty->staticProperty, so conceptually we don't need to check for both right now. However, the grammar can change, so it's probably good to be safe. pprkut: With the current grammer, if there's `staticProperty`, there's also a `staticProperty… | |||||
791 | // variable static properties ($object::${$property}) | ||||
792 | visitExpr(it->element->staticProperty->staticProperty->expr); | ||||
793 | usingDeclaration(it->element->staticProperty, DeclarationPointer()); | ||||
794 | } | ||||
795 | | ||||
766 | type = m_result.allDeclarations().last()->type<StructureType>(); | 796 | type = m_result.allDeclarations().last()->type<StructureType>(); | ||
767 | 797 | | |||
768 | if (!type) { | 798 | if (!type) { | ||
769 | context = nullptr; | 799 | context = nullptr; | ||
770 | continue; | 800 | continue; | ||
771 | } | 801 | } | ||
772 | 802 | | |||
773 | DUChainReadLocker lock(DUChain::lock()); | 803 | DUChainReadLocker lock(DUChain::lock()); | ||
774 | declaration = type->declaration(m_currentContext->topContext()); | 804 | declaration = type->declaration(m_currentContext->topContext()); | ||
775 | lock.unlock(); | 805 | lock.unlock(); | ||
776 | 806 | | |||
777 | if (!declaration) { | 807 | if (!declaration) { | ||
778 | context = nullptr; | 808 | context = nullptr; | ||
779 | continue; | 809 | continue; | ||
780 | } | 810 | } | ||
781 | 811 | | |||
782 | context = declaration->internalContext(); | 812 | context = declaration->internalContext(); | ||
783 | 813 | | |||
784 | if (!context || context->type() != DUContext::Class) { | 814 | if (!context || context->type() != DUContext::Class) { | ||
785 | context = nullptr; | 815 | context = nullptr; | ||
786 | continue; | 816 | continue; | ||
787 | } | 817 | } | ||
788 | 818 | | |||
789 | if (it->element->staticProperty) { | 819 | if (it->element->staticProperty && it->element->staticProperty->staticProperty->variable) { | ||
kfunk: Same here(?) | |||||
790 | // static properties ($object::$property) | 820 | // static properties ($object::$property) | ||
791 | VariableIdentifierAst *varnode = it->element->staticProperty->staticProperty->variable; | 821 | VariableIdentifierAst *varnode = it->element->staticProperty->staticProperty->variable; | ||
792 | useDeclaration(varnode, context); | 822 | useDeclaration(varnode, context); | ||
793 | } else if (it->element->property && it->element->property->objectDimList | 823 | } else if (it->element->property && it->element->property->objectDimList | ||
794 | && it->element->property->objectDimList->variableName->name) { | 824 | && it->element->property->objectDimList->variableName->name) { | ||
795 | // normal properties ($object->property) | 825 | // normal properties ($object->property) | ||
796 | IdentifierAst *varidnode = it->element->property->objectDimList->variableName->name; | 826 | IdentifierAst *varidnode = it->element->property->objectDimList->variableName->name; | ||
797 | useDeclaration(varidnode, context); | 827 | useDeclaration(varidnode, context); | ||
▲ Show 20 Lines • Show All 221 Lines • Show Last 20 Lines |
You already dereference node->staticProperty->staticProperty before in line 700; so this if-stmt would be always true(?). Doesn't make sense to me.