| 182 | } |
| 183 | |
| 184 | void CodeModel::addItem(const IndexedString& file, const IndexedQualifiedIdentifier& id, CodeModelItem::Kind kind) |
| 185 | { |
| 186 | ifDebug(qCDebug(LANGUAGE) << "addItem" << file.str() << id.identifier().toString() << id.index; ) |
| 187 | |
| 188 | if (!id.isValid()) |
| 189 | return; |
| 190 | CodeModelRepositoryItem item; |
| 191 | item.file = file; |
| 192 | CodeModelRequestItem request(item); |
| 193 | |
| 194 | CodeModelItem newItem; |
| 195 | newItem.id = id; |
| 196 | newItem.kind = kind; |
| 197 | newItem.referenceCount = 1; |
| 198 | |
| 199 | LockedItemRepository::write<CodeModel>([&](CodeModelRepo& repo) { |
| 200 | uint index = repo.findIndex(item); |
| 201 | |
| 202 | if (index) { |
| 203 | const CodeModelRepositoryItem* oldItem = repo.itemFromIndex(index); |
| 204 | EmbeddedTreeAlgorithms<CodeModelItem, CodeModelItemHandler> alg(oldItem->items(), oldItem->itemsSize(), |
| 205 | oldItem->centralFreeItem); |
| 206 | |
| 207 | int listIndex = alg.indexOf(newItem); |
| 208 | |
| 209 | DynamicItem<CodeModelRepositoryItem, true> editableItem = repo.dynamicItemFromIndex(index); |
| 210 | auto* items = const_cast<CodeModelItem*>(editableItem->items()); |
| 211 | |
| 212 | if (listIndex != -1) { |
| 213 | // Only update the reference-count |
| 214 | ++items[listIndex].referenceCount; |
| 215 | items[listIndex].kind = kind; |
| 216 | return; |
| 217 | } else { |
| 218 | // Add the item to the list |
| 219 | EmbeddedTreeAddItem<CodeModelItem, CodeModelItemHandler> add(items, editableItem->itemsSize(), |
| 220 | editableItem->centralFreeItem, newItem); |
| 221 | |
| 222 | if (add.newItemCount() != editableItem->itemsSize()) { |
| 223 | // The data needs to be transferred into a bigger list. That list is within "item". |
| 224 | |
| 225 | item.itemsList().resize(add.newItemCount()); |
| 226 | add.transferData(item.itemsList().data(), item.itemsList().size(), &item.centralFreeItem); |
| 227 | |
| 228 | repo.deleteItem(index); |
| 229 | } else { |
| 230 | // We're fine: The item fits into the existing list. |
| 231 | return; |
| 232 | } |
| 233 | } |
| 234 | } else { |
| 235 | // We're creating a new index |
| 236 | item.itemsList().append(newItem); |
| 237 | } |
| 238 | |
| 239 | Q_ASSERT(!repo.findIndex(request)); |
| 240 | |
| 241 | // This inserts the changed item |
no test coverage detected