| 352 | } |
| 353 | |
| 354 | static void buildFixItLine(std::string &CaretLine, std::string &FixItLine, |
| 355 | ArrayRef<SMFixIt> FixIts, |
| 356 | ArrayRef<char> SourceLine) { |
| 357 | if (FixIts.empty()) |
| 358 | return; |
| 359 | |
| 360 | const char *LineStart = SourceLine.begin(); |
| 361 | const char *LineEnd = SourceLine.end(); |
| 362 | |
| 363 | size_t PrevHintEndCol = 0; |
| 364 | |
| 365 | for (ArrayRef<SMFixIt>::iterator I = FixIts.begin(), E = FixIts.end(); I != E; |
| 366 | ++I) { |
| 367 | // If the fixit contains a newline or tab, ignore it. |
| 368 | if (I->getText().find_first_of("\n\r\t") != StringRef::npos) |
| 369 | continue; |
| 370 | |
| 371 | SMRange R = I->getRange(); |
| 372 | |
| 373 | // If the line doesn't contain any part of the range, then ignore it. |
| 374 | if (R.Start.getPointer() > LineEnd || R.End.getPointer() < LineStart) |
| 375 | continue; |
| 376 | |
| 377 | // Translate from SMLoc to column. |
| 378 | // Ignore pieces of the range that go onto other lines. |
| 379 | // FIXME: Handle multibyte characters in the source line. |
| 380 | unsigned FirstCol; |
| 381 | if (R.Start.getPointer() < LineStart) |
| 382 | FirstCol = 0; |
| 383 | else |
| 384 | FirstCol = R.Start.getPointer() - LineStart; |
| 385 | |
| 386 | // If we inserted a long previous hint, push this one forwards, and add |
| 387 | // an extra space to show that this is not part of the previous |
| 388 | // completion. This is sort of the best we can do when two hints appear |
| 389 | // to overlap. |
| 390 | // |
| 391 | // Note that if this hint is located immediately after the previous |
| 392 | // hint, no space will be added, since the location is more important. |
| 393 | unsigned HintCol = FirstCol; |
| 394 | if (HintCol < PrevHintEndCol) |
| 395 | HintCol = PrevHintEndCol + 1; |
| 396 | |
| 397 | // FIXME: This assertion is intended to catch unintended use of multibyte |
| 398 | // characters in fixits. If we decide to do this, we'll have to track |
| 399 | // separate byte widths for the source and fixit lines. |
| 400 | assert((size_t)sys::locale::columnWidth(I->getText()) == |
| 401 | I->getText().size()); |
| 402 | |
| 403 | // This relies on one byte per column in our fixit hints. |
| 404 | unsigned LastColumnModified = HintCol + I->getText().size(); |
| 405 | if (LastColumnModified > FixItLine.size()) |
| 406 | FixItLine.resize(LastColumnModified, ' '); |
| 407 | |
| 408 | std::copy(I->getText().begin(), I->getText().end(), |
| 409 | FixItLine.begin() + HintCol); |
| 410 | |
| 411 | PrevHintEndCol = LastColumnModified; |
no test coverage detected