@@ -381,6 +381,9 @@ namespace {
381381    };
382382
383383    unsigned  LineNumber;
384+     //  The line number displayed to the user. This may differ from the actual
385+     //  line number if #sourceLocation is used.
386+     unsigned  DisplayLineNumber;
384387    std::string LineText;
385388    SmallVector<Message, 1 > Messages;
386389    SmallVector<Highlight, 1 > Highlights;
@@ -448,8 +451,10 @@ namespace {
448451    }
449452
450453  public: 
451-     AnnotatedLine (unsigned  LineNumber, StringRef LineText)
452-         : LineNumber(LineNumber), LineText(LineText) {}
454+     AnnotatedLine (unsigned  LineNumber, unsigned  DisplayLineNumber,
455+                   StringRef LineText)
456+         : LineNumber(LineNumber), DisplayLineNumber(DisplayLineNumber),
457+           LineText (LineText) {}
453458
454459    unsigned  getLineNumber () { return  LineNumber; }
455460
@@ -469,7 +474,7 @@ namespace {
469474    }
470475
471476    void  render (unsigned  LineNumberIndent, raw_ostream &Out) {
472-       printNumberedGutter (LineNumber , LineNumberIndent, Out);
477+       printNumberedGutter (DisplayLineNumber , LineNumberIndent, Out);
473478
474479      //  Determine if the line is all-ASCII. This will determine a number of
475480      //  later formatting decisions.
@@ -628,21 +633,25 @@ namespace {
628633    // / diagnostic message. This is printed alongside the file path so it can be
629634    // / parsed by editors and other tooling.
630635    SourceLoc PrimaryLoc;
636+     // / Whether the excerpt is from a virtual file (e.g. one introduced using
637+     // / #sourceLocation).
638+     bool  FromVirtualFile;
631639    std::vector<AnnotatedLine> AnnotatedLines;
632640
633641    // / Return the AnnotatedLine for a given SourceLoc, creating it if it
634642    // / doesn't already exist.
635643    AnnotatedLine &lineForLoc (SourceLoc Loc) {
636-       //  FIXME: This call to `getLineAndColumn ` is expensive.
637-       unsigned  lineNo = SM.getLineAndColumn (Loc). first ;
638-       AnnotatedLine newLine (lineNo, " "  );
644+       //  FIXME: This call to `getLineNumber ` is expensive.
645+       unsigned  lineNo = SM.getLineNumber (Loc);
646+       AnnotatedLine newLine (lineNo, 0 ,  " "  );
639647      auto  iter =
640648          std::lower_bound (AnnotatedLines.begin (), AnnotatedLines.end (),
641649                           newLine, [](AnnotatedLine l1, AnnotatedLine l2) {
642650                             return  l1.getLineNumber () < l2.getLineNumber ();
643651                           });
644652      if  (iter == AnnotatedLines.end () || iter->getLineNumber () != lineNo) {
645653        newLine.LineText  = SM.getLineString (BufferID, lineNo);
654+         newLine.DisplayLineNumber  = SM.getLineAndColumn (Loc).first ;
646655        return  *AnnotatedLines.insert (iter, newLine);
647656      } else  {
648657        return  *iter;
@@ -658,10 +667,8 @@ namespace {
658667
659668    void  lineRangesForRange (CharSourceRange Range,
660669                            SmallVectorImpl<CharSourceRange> &LineRanges) {
661-       //  FIXME: The calls to `getLineAndColumn` and `getLocForLineCol` are
662-       //  expensive.
663-       unsigned  startLineNo = SM.getLineAndColumn (Range.getStart ()).first ;
664-       unsigned  endLineNo = SM.getLineAndColumn (Range.getEnd ()).first ;
670+       unsigned  startLineNo = SM.getLineNumber (Range.getStart ());
671+       unsigned  endLineNo = SM.getLineNumber (Range.getEnd ());
665672
666673      if  (startLineNo == endLineNo) {
667674        LineRanges.push_back (Range);
@@ -687,10 +694,19 @@ namespace {
687694      LineRanges.push_back (CharSourceRange (SM, lastLineStart, Range.getEnd ()));
688695    }
689696
697+     void  printLineEllipsis (raw_ostream &Out) {
698+       Out.changeColor (ColoredStream::Colors::CYAN, true );
699+       Out << llvm::formatv (" {0}...\n "  ,
700+                            llvm::fmt_repeat ("  "  , getPreferredLineNumberIndent ()));
701+       Out.resetColor ();
702+     }
703+ 
690704  public: 
691705    AnnotatedFileExcerpt (SourceManager &SM, unsigned  BufferID,
692706                         SourceLoc PrimaryLoc)
693-         : SM(SM), BufferID(BufferID), PrimaryLoc(PrimaryLoc) {}
707+         : SM(SM), BufferID(BufferID), PrimaryLoc(PrimaryLoc) {
708+       FromVirtualFile = SM.isLocInVirtualFile (PrimaryLoc);
709+     }
694710
695711    unsigned  getPreferredLineNumberIndent () {
696712      //  The lines are already in sorted ascending order, and we render one line
@@ -734,13 +750,14 @@ namespace {
734750      auto  primaryLineAndColumn = SM.getLineAndColumn (PrimaryLoc);
735751      Out.changeColor (ColoredStream::Colors::CYAN);
736752      Out << std::string (lineNumberIndent + 1 , ' ='  ) << "  " 
737-           << SM.getIdentifierForBuffer (BufferID ) << " :" 
753+           << SM.getDisplayNameForLoc (PrimaryLoc ) << " :" 
738754          << primaryLineAndColumn.first  << " :"   << primaryLineAndColumn.second 
739755          << "  "   << std::string (lineNumberIndent + 1 , ' ='  ) << " \n "  ;
740756      Out.resetColor ();
741757
742-       //  Print one extra line at the top for context.
743-       if  (AnnotatedLines.front ().getLineNumber () > 1 )
758+       //  Print one extra line at the top for context, so long as this isn't an
759+       //  excerpt from a virtual file.
760+       if  (AnnotatedLines.front ().getLineNumber () > 1  && !FromVirtualFile)
744761        printNumberedLine (SM, BufferID,
745762                          AnnotatedLines.front ().getLineNumber () - 1 ,
746763                          lineNumberIndent, Out);
@@ -754,14 +771,18 @@ namespace {
754771      for  (auto  line = AnnotatedLines.begin () + 1 ; line != AnnotatedLines.end ();
755772           ++line) {
756773        unsigned  lineNumber = line->getLineNumber ();
757-         if  (lineNumber - lastLineNumber > maxIntermediateLines) {
774+         if  (FromVirtualFile) {
775+           //  Don't print intermediate lines in virtual files, as they may not
776+           //  make sense in context. Instead, just print an ellipsis between them
777+           //  if they're not consecutive in the actual source file.
778+           if  (lineNumber - lastLineNumber > 1 ) {
779+             printLineEllipsis (Out);
780+           }
781+         } else  if  (lineNumber - lastLineNumber > maxIntermediateLines) {
758782          //  Use an ellipsis to denote an ommitted part of the file.
759783          printNumberedLine (SM, BufferID, lastLineNumber + 1 , lineNumberIndent,
760784                            Out);
761-           Out.changeColor (ColoredStream::Colors::CYAN);
762-           Out << llvm::formatv (" {0}...\n "  ,
763-                                llvm::fmt_repeat ("  "  , lineNumberIndent));
764-           Out.resetColor ();
785+           printLineEllipsis (Out);
765786          printNumberedLine (SM, BufferID, lineNumber - 1 , lineNumberIndent,
766787                            Out);
767788        } else  {
@@ -774,11 +795,14 @@ namespace {
774795        line->render (lineNumberIndent, Out);
775796        lastLineNumber = lineNumber;
776797      }
777-       //  Print one extra line at the bottom for context.
778-       printNumberedLine (
779-           SM, BufferID,
780-           AnnotatedLines[AnnotatedLines.size () - 1 ].getLineNumber () + 1 ,
781-           lineNumberIndent, Out);
798+       //  Print one extra line at the bottom for context, so long as the excerpt
799+       //  isn't from a virtual file.
800+       if  (!FromVirtualFile) {
801+         printNumberedLine (
802+             SM, BufferID,
803+             AnnotatedLines[AnnotatedLines.size () - 1 ].getLineNumber () + 1 ,
804+             lineNumberIndent, Out);
805+       }
782806    }
783807  };
784808} //  end anonymous namespace
@@ -788,14 +812,17 @@ namespace swift {
788812// / complete diagnostic message.
789813class  AnnotatedSourceSnippet  {
790814  SourceManager &SM;
791-   std::map<unsigned , AnnotatedFileExcerpt> FileExcerpts;
815+   std::map<StringRef , AnnotatedFileExcerpt> FileExcerpts;
792816  SmallVector<std::pair<DiagnosticKind, std::string>, 1 >
793817      UnknownLocationMessages;
794818
795819  AnnotatedFileExcerpt &excerptForLoc (SourceLoc Loc) {
820+     StringRef bufName = SM.getDisplayNameForLoc (Loc);
796821    unsigned  bufID = SM.findBufferContainingLoc (Loc);
797-     FileExcerpts.emplace (bufID, AnnotatedFileExcerpt (SM, bufID, Loc));
798-     return  FileExcerpts.find (bufID)->second ;
822+     //  Use the buffer display name as the key in the excerpt map instead of the
823+     //  buffer identifier to respect #sourceLocation directives.
824+     FileExcerpts.emplace (bufName, AnnotatedFileExcerpt (SM, bufID, Loc));
825+     return  FileExcerpts.find (bufName)->second ;
799826  }
800827
801828public: 
0 commit comments