@@ -35,30 +35,20 @@ struct ExpectedFixIt {
3535};
3636} // end namespace swift
3737
38- constexpr unsigned LineColumnRange::NoValue;
39-
4038const LineColumnRange &
4139CapturedFixItInfo::getLineColumnRange (const SourceManager &SM,
42- unsigned BufferID,
43- bool ComputeStartLocLine,
44- bool ComputeEndLocLine) const {
45- if (LineColRange.StartLine == LineColumnRange::NoValue &&
46- ComputeStartLocLine) {
47- std::tie (LineColRange.StartLine , LineColRange.StartCol ) =
48- SM.getPresumedLineAndColumnForLoc (getSourceRange ().getStart (),
49- BufferID);
50- } else if (LineColRange.StartCol == LineColumnRange::NoValue) {
51- LineColRange.StartCol =
52- SM.getColumnInBuffer (getSourceRange ().getStart (), BufferID);
40+ unsigned BufferID) const {
41+ if (LineColRange.StartLine != 0 ) {
42+ // Already computed.
43+ return LineColRange;
5344 }
5445
55- if (LineColRange.EndLine == LineColumnRange::NoValue && ComputeEndLocLine) {
56- std::tie (LineColRange.EndLine , LineColRange.EndCol ) =
57- SM.getPresumedLineAndColumnForLoc (FixIt.getRange ().getEnd (), BufferID);
58- } else if (LineColRange.EndCol == LineColumnRange::NoValue) {
59- LineColRange.EndCol =
60- SM.getColumnInBuffer (getSourceRange ().getEnd (), BufferID);
61- }
46+ auto SrcRange = FixIt.getRange ();
47+
48+ std::tie (LineColRange.StartLine , LineColRange.StartCol ) =
49+ SM.getPresumedLineAndColumnForLoc (SrcRange.getStart (), BufferID);
50+ std::tie (LineColRange.EndLine , LineColRange.EndCol ) =
51+ SM.getPresumedLineAndColumnForLoc (SrcRange.getEnd (), BufferID);
6252
6353 return LineColRange;
6454}
@@ -293,23 +283,11 @@ bool DiagnosticVerifier::checkForFixIt(
293283 if (ActualFixIt.getText () != Expected.Text )
294284 continue ;
295285
296- LineColumnRange ActualRange = ActualFixIt.getLineColumnRange (
297- SM, BufferID,
298- // Don't compute line numbers unless we have to.
299- /* ComputeStartLocLine=*/ Expected.Range .StartLine !=
300- LineColumnRange::NoValue,
301- /* ComputeEndLocLine=*/ Expected.Range .EndLine !=
302- LineColumnRange::NoValue);
286+ auto &ActualRange = ActualFixIt.getLineColumnRange (SM, BufferID);
303287
304288 if (Expected.Range .StartCol != ActualRange.StartCol ||
305- Expected.Range .EndCol != ActualRange.EndCol ) {
306- continue ;
307- }
308- if (Expected.Range .StartLine != LineColumnRange::NoValue &&
309- Expected.Range .StartLine != ActualRange.StartLine ) {
310- continue ;
311- }
312- if (Expected.Range .EndLine != LineColumnRange::NoValue &&
289+ Expected.Range .EndCol != ActualRange.EndCol ||
290+ Expected.Range .StartLine != ActualRange.StartLine ||
313291 Expected.Range .EndLine != ActualRange.EndLine ) {
314292 continue ;
315293 }
@@ -329,10 +307,7 @@ DiagnosticVerifier::renderFixits(ArrayRef<CapturedFixItInfo> ActualFixIts,
329307 interleave (
330308 ActualFixIts,
331309 [&](const CapturedFixItInfo &ActualFixIt) {
332- LineColumnRange ActualRange =
333- ActualFixIt.getLineColumnRange (SM, BufferID,
334- /* ComputeStartLocLine=*/ true ,
335- /* ComputeEndLocLine=*/ true );
310+ auto &ActualRange = ActualFixIt.getLineColumnRange (SM, BufferID);
336311 OS << " {{" ;
337312
338313 if (ActualRange.StartLine != DiagnosticLineNo)
@@ -372,83 +347,85 @@ static Optional<LineColumnRange> parseExpectedFixItRange(
372347 llvm::function_ref<void (const char *, const Twine &)> diagnoseError) {
373348 assert (!Str.empty ());
374349
375- const auto parseLineAndColumn =
376- [&]() -> Optional<std::pair<unsigned , unsigned >> {
377- enum class LineOffsetKind : uint8_t { None, Plus, Minus };
350+ struct ParsedLineAndColumn {
351+ Optional<unsigned > Line;
352+ unsigned Column;
353+ };
378354
379- LineOffsetKind lineOffsetKind = LineOffsetKind::None;
355+ const auto parseLineAndColumn = [&]() -> Optional<ParsedLineAndColumn> {
356+ enum class OffsetKind : uint8_t { None, Plus, Minus };
357+
358+ OffsetKind LineOffsetKind = OffsetKind::None;
380359 if (!Str.empty ()) {
381360 switch (Str.front ()) {
382361 case ' +' :
383- lineOffsetKind = LineOffsetKind ::Plus;
362+ LineOffsetKind = OffsetKind ::Plus;
384363 Str = Str.drop_front ();
385364 break ;
386365 case ' -' :
387- lineOffsetKind = LineOffsetKind ::Minus;
366+ LineOffsetKind = OffsetKind ::Minus;
388367 Str = Str.drop_front ();
389368 break ;
390369 default :
391370 break ;
392371 }
393372 }
394373
395- unsigned firstNumber = LineColumnRange::NoValue ;
396- if (Str.consumeInteger (10 , firstNumber )) {
397- if (lineOffsetKind > LineOffsetKind ::None) {
374+ unsigned FirstVal = 0 ;
375+ if (Str.consumeInteger (10 , FirstVal )) {
376+ if (LineOffsetKind == OffsetKind ::None) {
398377 diagnoseError (Str.data (),
399- " expected line offset after leading '+' or '-' in fix-it "
400- " verification" );
378+ " expected line or column number in fix-it verification" );
401379 } else {
402380 diagnoseError (Str.data (),
403- " expected line or column number in fix-it verification" );
381+ " expected line offset after leading '+' or '-' in fix-it "
382+ " verification" );
404383 }
405384 return None;
406385 }
407386
408- unsigned secondNumber = LineColumnRange::NoValue;
409- if (!Str.empty () && Str.front () == ' :' ) {
410- Str = Str.drop_front ();
411-
412- if (Str.consumeInteger (10 , secondNumber)) {
413- diagnoseError (
414- Str.data (),
415- " expected column number after ':' in fix-it verification" );
416- return None;
387+ // If the first value is not followed by a colon, it is either a column or a
388+ // line offset that is missing a column.
389+ if (Str.empty () || Str.front () != ' :' ) {
390+ if (LineOffsetKind == OffsetKind::None) {
391+ return ParsedLineAndColumn{None, FirstVal};
417392 }
418- } else if (lineOffsetKind > LineOffsetKind::None) {
393+
419394 diagnoseError (Str.data (),
420395 " expected colon-separated column number after line offset "
421396 " in fix-it verification" );
422397 return None;
423398 }
424399
425- if (secondNumber == LineColumnRange::NoValue) {
426- // If only one value is specified, it's a column number;
427- return std::make_pair (LineColumnRange::NoValue, firstNumber);
400+ unsigned Column = 0 ;
401+ Str = Str.drop_front ();
402+ if (Str.consumeInteger (10 , Column)) {
403+ diagnoseError (Str.data (),
404+ " expected column number after ':' in fix-it verification" );
405+ return None;
428406 }
429407
430- unsigned lineNo = DiagnosticLineNo;
431- switch (lineOffsetKind) {
432- case LineOffsetKind::None:
433- lineNo = firstNumber;
408+ // Apply the offset relative to the line of the expected diagnostic.
409+ switch (LineOffsetKind) {
410+ case OffsetKind::None:
434411 break ;
435- case LineOffsetKind ::Plus:
436- lineNo += firstNumber ;
412+ case OffsetKind ::Plus:
413+ FirstVal += DiagnosticLineNo ;
437414 break ;
438- case LineOffsetKind ::Minus:
439- lineNo -= firstNumber ;
415+ case OffsetKind ::Minus:
416+ FirstVal = DiagnosticLineNo - FirstVal ;
440417 break ;
441418 }
442419
443- return std::make_pair (lineNo, secondNumber) ;
420+ return ParsedLineAndColumn{FirstVal, Column} ;
444421 };
445422
446423 LineColumnRange Range;
447424
448- if (const auto lineAndCol = parseLineAndColumn ()) {
449- std::tie (Range. StartLine , Range. StartCol ) = lineAndCol. value ();
450- if ( Range.StartLine == LineColumnRange::NoValue)
451- Range.StartLine = DiagnosticLineNo ;
425+ if (const auto LineAndCol = parseLineAndColumn ()) {
426+ // The start line defaults to the line of the expected diagnostic.
427+ Range.StartLine = LineAndCol-> Line . value_or (DiagnosticLineNo);
428+ Range.StartCol = LineAndCol-> Column ;
452429 } else {
453430 return None;
454431 }
@@ -461,10 +438,10 @@ static Optional<LineColumnRange> parseExpectedFixItRange(
461438 return None;
462439 }
463440
464- if (const auto lineAndCol = parseLineAndColumn ()) {
465- std::tie (Range. EndLine , Range. EndCol ) = lineAndCol. value ();
466- if ( Range.EndLine == LineColumnRange::NoValue)
467- Range.EndLine = Range. StartLine ;
441+ if (const auto LineAndCol = parseLineAndColumn ()) {
442+ // The end line defaults to the start line.
443+ Range.EndLine = LineAndCol-> Line . value_or (Range. StartLine );
444+ Range.EndCol = LineAndCol-> Column ;
468445 } else {
469446 return None;
470447 }
0 commit comments