* Arrays */
| 474 | * Arrays |
| 475 | */ |
| 476 | void DeclarationBuilder::declareFieldMember(const KDevelop::DeclarationPointer& declaration, |
| 477 | const QString& member, |
| 478 | QmlJS::AST::Node* node, |
| 479 | const QmlJS::AST::SourceLocation& location) |
| 480 | { |
| 481 | if (QmlJS::isPrototypeIdentifier(member)) { |
| 482 | // Don't declare "prototype", this is a special member |
| 483 | return; |
| 484 | } |
| 485 | |
| 486 | if (!m_session->allDependenciesSatisfied()) { |
| 487 | // Don't declare anything automatically if dependencies are missing: the |
| 488 | // checks hereafter may pass now but fail later, thus causing disappearing |
| 489 | // declarations |
| 490 | return; |
| 491 | } |
| 492 | |
| 493 | DUChainWriteLocker lock; |
| 494 | Identifier identifier(member); |
| 495 | |
| 496 | // Declaration must have an internal context so that the member can be added |
| 497 | // into it. |
| 498 | DUContext* ctx = QmlJS::getInternalContext(declaration); |
| 499 | |
| 500 | if (!ctx || ctx->topContext() != topContext()) { |
| 501 | return; |
| 502 | } |
| 503 | |
| 504 | // No need to re-declare a field if it already exists |
| 505 | // TODO check if we can make getDeclaration receive an Identifier directly |
| 506 | if (QmlJS::getDeclaration(QualifiedIdentifier(identifier), ctx, false)) { |
| 507 | return; |
| 508 | } |
| 509 | |
| 510 | // The internal context of declaration is already closed and does not contain |
| 511 | // location. This can be worked around by opening a new context, declaring the |
| 512 | // new field in it, and then adding the context as a parent of |
| 513 | // declaration->internalContext(). |
| 514 | RangeInRevision range = m_session->locationToRange(location); |
| 515 | IntegralType::Ptr type = IntegralType::Ptr(new IntegralType(IntegralType::TypeMixed)); |
| 516 | DUContext* importedContext = openContext(node, range, DUContext::Class); |
| 517 | auto* decl = openDeclaration<Declaration>(identifier, range); |
| 518 | |
| 519 | decl->setInSymbolTable(false); // This declaration is in an anonymous context, and the symbol table acts as if the declaration was in the global context |
| 520 | openType(type); |
| 521 | closeAndAssignType(); |
| 522 | closeContext(); |
| 523 | |
| 524 | ctx->addImportedParentContext(importedContext); |
| 525 | } |
| 526 | |
| 527 | bool DeclarationBuilder::visit(QmlJS::AST::FieldMemberExpression* node) |
| 528 | { |
nothing calls this directly
no test coverage detected