| 191 | } |
| 192 | |
| 193 | void DUContextDynamicData::addDeclaration(Declaration* newDeclaration) |
| 194 | { |
| 195 | // The definition may not have its identifier set when it's assigned... |
| 196 | // allow dupes here, TODO catch the error elsewhere |
| 197 | |
| 198 | //If this context is temporary, added declarations should be as well, and viceversa |
| 199 | Q_ASSERT(isContextTemporary(m_indexInTopContext) == isContextTemporary(newDeclaration->ownIndex())); |
| 200 | |
| 201 | CursorInRevision start = newDeclaration->range().start; |
| 202 | |
| 203 | bool inserted = false; |
| 204 | ///@todo Do binary search to find the position |
| 205 | for (int i = m_localDeclarations.size() - 1; i >= 0; --i) { |
| 206 | Declaration* child = m_localDeclarations[i]; |
| 207 | Q_ASSERT(d_func()->m_localDeclarations()[i].data(m_topContext) == child); |
| 208 | if (child == newDeclaration) |
| 209 | return; |
| 210 | //TODO: All declarations in a macro will have the same empty range, and just get appended |
| 211 | //that may not be Good Enough in complex cases. |
| 212 | if (start >= child->range().start) { |
| 213 | m_localDeclarations.insert(i + 1, newDeclaration); |
| 214 | d_func_dynamic()->m_localDeclarationsList().insert(i + 1, newDeclaration); |
| 215 | Q_ASSERT(d_func()->m_localDeclarations()[i + 1].data(m_topContext) == newDeclaration); |
| 216 | |
| 217 | inserted = true; |
| 218 | break; |
| 219 | } |
| 220 | } |
| 221 | |
| 222 | if (!inserted) { |
| 223 | // We haven't found any child that is before this one, so prepend it |
| 224 | m_localDeclarations.insert(0, newDeclaration); |
| 225 | auto& declarations = d_func_dynamic()->m_localDeclarationsList(); |
| 226 | declarations.insert(declarations.begin(), newDeclaration); |
| 227 | Q_ASSERT(declarations[0].data(m_topContext) == newDeclaration); |
| 228 | } |
| 229 | } |
| 230 | |
| 231 | bool DUContextDynamicData::removeDeclaration(Declaration* declaration) |
| 232 | { |