@@ -600,38 +600,46 @@ mapOffsetToNewerSnapshot(unsigned Offset,
600
600
return None;
601
601
}
602
602
603
- // / Tries to remap the location from a previous snapshot to the latest one.
604
- static llvm::Optional<std::pair<unsigned , unsigned >>
605
- tryRemappingLocToLatestSnapshot (SwiftLangSupport &Lang,
606
- std::pair<unsigned , unsigned > Range,
607
- StringRef Filename,
608
- ArrayRef<ImmutableTextSnapshotRef> PreviousASTSnaps) {
609
- ImmutableTextSnapshotRef LatestSnap;
610
- if (auto EditorDoc = Lang.getEditorDocuments ()->findByPath (Filename))
611
- LatestSnap = EditorDoc->getLatestSnapshot ();
603
+ // / Tries to remap the location from a previous snapshot to the latest one and
604
+ // / then sets the location's line and column.
605
+ static void mapLocToLatestSnapshot (
606
+ SwiftLangSupport &Lang, LocationInfo &Location,
607
+ ArrayRef<ImmutableTextSnapshotRef> PreviousASTSnaps) {
608
+ auto EditorDoc = Lang.getEditorDocuments ()->findByPath (Location.Filename );
609
+ if (!EditorDoc)
610
+ return ;
611
+
612
+ ImmutableTextSnapshotRef LatestSnap = EditorDoc->getLatestSnapshot ();
612
613
if (!LatestSnap)
613
- return Range ;
614
+ return ;
614
615
615
616
for (auto &PrevSnap : PreviousASTSnaps) {
616
617
if (PrevSnap->isFromSameBuffer (LatestSnap)) {
617
618
if (PrevSnap->getStamp () == LatestSnap->getStamp ())
618
- return Range ;
619
+ break ;
619
620
620
- auto OptBegin = mapOffsetToNewerSnapshot (Range. first ,
621
+ auto OptBegin = mapOffsetToNewerSnapshot (Location. Offset ,
621
622
PrevSnap, LatestSnap);
622
- if (!OptBegin.hasValue ())
623
- return None;
623
+ if (!OptBegin.hasValue ()) {
624
+ Location.Filename = StringRef ();
625
+ return ;
626
+ }
624
627
625
- auto OptEnd = mapOffsetToNewerSnapshot (Range.first +Range.second ,
628
+ auto OptEnd = mapOffsetToNewerSnapshot (Location.Offset +
629
+ Location.Length ,
626
630
PrevSnap, LatestSnap);
627
- if (!OptEnd.hasValue ())
628
- return None;
631
+ if (!OptEnd.hasValue ()) {
632
+ Location.Filename = StringRef ();
633
+ return ;
634
+ }
629
635
630
- return std::make_pair (*OptBegin, *OptEnd-*OptBegin);
636
+ Location.Offset = *OptBegin;
637
+ Location.Length = *OptEnd - *OptBegin;
631
638
}
632
639
}
633
640
634
- return Range;
641
+ std::tie (Location.Line , Location.Column ) =
642
+ EditorDoc->getLineAndColumn (Location.Offset );
635
643
}
636
644
637
645
@@ -802,6 +810,106 @@ static ArrayRef<T> copyAndClearArray(llvm::BumpPtrAllocator &Allocator,
802
810
return Ref;
803
811
}
804
812
813
+ static void setLocationInfoForClangNode (ClangNode ClangNode,
814
+ ClangImporter *Importer,
815
+ LocationInfo &Location) {
816
+ clang::ASTContext &ClangCtx = Importer->getClangASTContext ();
817
+ clang::SourceManager &ClangSM = ClangCtx.getSourceManager ();
818
+
819
+ clang::SourceRange SR = ClangNode.getLocation ();
820
+ if (auto MD = dyn_cast_or_null<clang::ObjCMethodDecl>(ClangNode.getAsDecl ())) {
821
+ SR = clang::SourceRange (MD->getSelectorStartLoc (),
822
+ MD->getDeclaratorEndLoc ());
823
+ }
824
+
825
+ clang::CharSourceRange CharRange =
826
+ clang::Lexer::makeFileCharRange (clang::CharSourceRange::getTokenRange (SR),
827
+ ClangSM, ClangCtx.getLangOpts ());
828
+ if (CharRange.isInvalid ())
829
+ return ;
830
+
831
+ std::pair<clang::FileID, unsigned >
832
+ Decomp = ClangSM.getDecomposedLoc (CharRange.getBegin ());
833
+ if (!Decomp.first .isInvalid ()) {
834
+ if (auto FE = ClangSM.getFileEntryForID (Decomp.first )) {
835
+ Location.Filename = FE->getName ();
836
+
837
+ std::pair<clang::FileID, unsigned >
838
+ EndDecomp = ClangSM.getDecomposedLoc (CharRange.getEnd ());
839
+
840
+ Location.Offset = Decomp.second ;
841
+ Location.Length = EndDecomp.second -Decomp.second ;
842
+ Location.Line = ClangSM.getLineNumber (Decomp.first , Decomp.second );
843
+ Location.Column = ClangSM.getColumnNumber (Decomp.first , Decomp.second );
844
+ }
845
+ }
846
+ }
847
+
848
+ static unsigned getCharLength (SourceManager &SM, SourceRange TokenRange) {
849
+ SourceLoc CharEndLoc = Lexer::getLocForEndOfToken (SM, TokenRange.End );
850
+ return SM.getByteDistance (TokenRange.Start , CharEndLoc);
851
+ }
852
+
853
+ static void setLocationInfo (const ValueDecl *VD,
854
+ LocationInfo &Location) {
855
+ ASTContext &Ctx = VD->getASTContext ();
856
+ SourceManager &SM = Ctx.SourceMgr ;
857
+
858
+ auto ClangNode = VD->getClangNode ();
859
+
860
+ SourceLoc Loc = VD->getLoc (/* SerializedOK=*/ false );
861
+ if (Loc.isValid ()) {
862
+ auto getSignatureRange = [&](const ValueDecl *VD) -> Optional<unsigned > {
863
+ if (auto FD = dyn_cast<AbstractFunctionDecl>(VD)) {
864
+ SourceRange R = FD->getSignatureSourceRange ();
865
+ if (R.isValid ())
866
+ return getCharLength (SM, R);
867
+ }
868
+ return None;
869
+ };
870
+ unsigned NameLen;
871
+ if (auto SigLen = getSignatureRange (VD)) {
872
+ NameLen = SigLen.getValue ();
873
+ } else if (VD->hasName ()) {
874
+ NameLen = VD->getBaseName ().userFacingName ().size ();
875
+ } else {
876
+ NameLen = getCharLength (SM, Loc);
877
+ }
878
+
879
+ unsigned DeclBufID = SM.findBufferContainingLoc (Loc);
880
+ Location.Filename = SM.getIdentifierForBuffer (DeclBufID);
881
+ Location.Offset = SM.getLocOffsetInBuffer (Loc, DeclBufID);
882
+ Location.Length = NameLen;
883
+ std::tie (Location.Line , Location.Column ) = SM.getLineAndColumnInBuffer (
884
+ Loc, DeclBufID);
885
+ } else if (auto *Positions =
886
+ VD->getSerializedLocs (/* Resolve=*/ false ).Positions ) {
887
+ Location.Filename = Positions->SourceFilePath ;
888
+
889
+ // Only add position information if the file is up to date
890
+ if (auto *File = dyn_cast<LoadedFile>(
891
+ VD->getDeclContext ()->getModuleScopeContext ())) {
892
+ File->collectBasicSourceFileInfo ([&](const BasicSourceFileInfo &Info) {
893
+ auto Stat = SM.getFileSystem ()->status (Info.getFilePath ());
894
+ if (!Stat)
895
+ return ;
896
+
897
+ if (Stat->getLastModificationTime () == Info.getLastModified () &&
898
+ Stat->getSize () == Info.getFileSize ()) {
899
+ Location.Offset = Positions->Loc .Offset ;
900
+ Location.Length = 0 ;
901
+ Location.Line = Positions->Loc .Line ;
902
+ Location.Column = Positions->Loc .Column ;
903
+ }
904
+ });
905
+ }
906
+ } else if (ClangNode) {
907
+ ClangImporter *Importer =
908
+ static_cast <ClangImporter*>(Ctx.getClangModuleLoader ());
909
+ setLocationInfoForClangNode (ClangNode, Importer, Location);
910
+ }
911
+ }
912
+
805
913
static llvm::Error
806
914
fillSymbolInfo (CursorSymbolInfo &Symbol, const DeclInfo &DInfo,
807
915
ModuleDecl *MainModule, SourceLoc CursorLoc, bool AddSymbolGraph,
@@ -934,12 +1042,10 @@ fillSymbolInfo(CursorSymbolInfo &Symbol, const DeclInfo &DInfo,
934
1042
Lang.getIFaceGenContexts ().find (Symbol.ModuleName , Invoc))
935
1043
Symbol.ModuleInterfaceName = IFaceGenRef->getDocumentName ();
936
1044
937
- getLocationInfo (DInfo.OriginalProperty , Symbol.DeclarationLoc ,
938
- Symbol.Filename );
939
- if (Symbol.DeclarationLoc .hasValue ()) {
940
- Symbol.DeclarationLoc = tryRemappingLocToLatestSnapshot (
941
- Lang, *Symbol.DeclarationLoc , Symbol.Filename , PreviousSnaps);
942
- if (!Symbol.DeclarationLoc .hasValue ()) {
1045
+ setLocationInfo (DInfo.OriginalProperty , Symbol.Location );
1046
+ if (!Symbol.Location .Filename .empty ()) {
1047
+ mapLocToLatestSnapshot (Lang, Symbol.Location , PreviousSnaps);
1048
+ if (Symbol.Location .Filename .empty ()) {
943
1049
return llvm::createStringError (
944
1050
llvm::inconvertibleErrorCode (),
945
1051
" Failed to remap declaration to latest snapshot." );
0 commit comments