hokein created this revision.
hokein added a reviewer: sammccall.
Herald added subscribers: MaskRay, ioeric, jkorous-apple, ilya-biryukov, klimek.
LSP is using Line & column as symbol position, clangd needs to transfer file
offset to Line & column when sending results back to LSP client, which is a high
cost, especially for finding workspace symbol -- we have to read the file
content from disk (if it isn't loaded in memory).

Saving these information in the index will make the clangd life eaiser.


Repository:
  rCTE Clang Tools Extra

https://reviews.llvm.org/D45513

Files:
  clangd/index/Index.h
  clangd/index/SymbolCollector.cpp
  clangd/index/SymbolYAML.cpp
  unittests/clangd/SymbolCollectorTests.cpp

Index: unittests/clangd/SymbolCollectorTests.cpp
===================================================================
--- unittests/clangd/SymbolCollectorTests.cpp
+++ unittests/clangd/SymbolCollectorTests.cpp
@@ -59,6 +59,21 @@
   return arg.Definition.StartOffset == Offsets.first &&
          arg.Definition.EndOffset == Offsets.second;
 }
+MATCHER_P(DeclRangePos, Pos, "") {
+  return std::tie(arg.CanonicalDeclaration.StartPos.Line,
+                  arg.CanonicalDeclaration.StartPos.Character,
+                  arg.CanonicalDeclaration.EndPos.Line,
+                  arg.CanonicalDeclaration.EndPos.Character) ==
+         std::tie(Pos.start.line, Pos.start.character, Pos.end.line,
+                  Pos.end.character);
+}
+MATCHER_P(DefRangePos, Pos, "") {
+  return std::tie(arg.Definition.StartPos.Line,
+                  arg.Definition.StartPos.Character, arg.Definition.EndPos.Line,
+                  arg.Definition.EndPos.Character) ==
+         std::tie(Pos.start.line, Pos.start.character, Pos.end.line,
+                  Pos.end.character);
+}
 MATCHER_P(Refs, R, "") { return int(arg.References) == R; }
 
 namespace clang {
@@ -209,7 +224,8 @@
   )");
   runSymbolCollector(Header.code(), /*Main=*/"");
   EXPECT_THAT(Symbols, UnorderedElementsAreArray({AllOf(
-                           QName("Tmpl"), DeclRange(Header.offsetRange()))}));
+                           QName("Tmpl"), DeclRange(Header.offsetRange()),
+                           DeclRangePos(Header.range()))}));
 }
 
 TEST_F(SymbolCollectorTest, Locations) {
@@ -234,13 +250,24 @@
   EXPECT_THAT(
       Symbols,
       UnorderedElementsAre(
-          AllOf(QName("X"), DeclRange(Header.offsetRange("xdecl")),
-                DefRange(Main.offsetRange("xdef"))),
-          AllOf(QName("Cls"), DeclRange(Header.offsetRange("clsdecl")),
-                DefRange(Main.offsetRange("clsdef"))),
-          AllOf(QName("print"), DeclRange(Header.offsetRange("printdecl")),
-                DefRange(Main.offsetRange("printdef"))),
-          AllOf(QName("Z"), DeclRange(Header.offsetRange("zdecl")))));
+          AllOf(QName("X"),
+                DeclRange(Header.offsetRange("xdecl")),
+                DeclRangePos(Header.range("xdecl")),
+                DefRange(Main.offsetRange("xdef")),
+                DefRangePos(Main.range("xdef"))),
+          AllOf(QName("Cls"),
+                DeclRange(Header.offsetRange("clsdecl")),
+                DeclRangePos(Header.range("clsdecl")),
+                DefRange(Main.offsetRange("clsdef")),
+                DefRangePos(Main.range("clsdef"))),
+          AllOf(QName("print"),
+                DeclRange(Header.offsetRange("printdecl")),
+                DeclRangePos(Header.range("printdecl")),
+                DefRange(Main.offsetRange("printdef")),
+                DefRangePos(Main.range("printdef"))),
+          AllOf(QName("Z"),
+                DeclRange(Header.offsetRange("zdecl")),
+                DeclRangePos(Header.range("zdecl")))));
 }
 
 TEST_F(SymbolCollectorTest, References) {
@@ -365,9 +392,13 @@
   EXPECT_THAT(
       Symbols,
       UnorderedElementsAre(
-          AllOf(QName("abc_Test"), DeclRange(Header.offsetRange("expansion")),
+          AllOf(QName("abc_Test"),
+                DeclRange(Header.offsetRange("expansion")),
+                DeclRangePos(Header.range("expansion")),
                 DeclURI(TestHeaderURI)),
-          AllOf(QName("Test"), DeclRange(Header.offsetRange("spelling")),
+          AllOf(QName("Test"),
+                DeclRange(Header.offsetRange("spelling")),
+                DeclRangePos(Header.range("spelling")),
                 DeclURI(TestHeaderURI))));
 }
 
@@ -382,7 +413,9 @@
                      /*ExtraArgs=*/{"-DNAME=name"});
   EXPECT_THAT(Symbols,
               UnorderedElementsAre(AllOf(
-                  QName("name"), DeclRange(Header.offsetRange("expansion")),
+                  QName("name"),
+                  DeclRange(Header.offsetRange("expansion")),
+                  DeclRangePos(Header.range("expansion")),
                   DeclURI(TestHeaderURI))));
 }
 
@@ -514,6 +547,12 @@
   StartOffset:     0
   EndOffset:       1
   FileURI:        file:///path/foo.h
+  StartPos:
+    line: 0
+    character: 0
+  EndPos:
+    line: 0
+    character: 1
 CompletionLabel:    'Foo1-label'
 CompletionFilterText:    'filter'
 CompletionPlainInsertText:    'plain'
@@ -534,6 +573,12 @@
   StartOffset:     10
   EndOffset:       12
   FileURI:        file:///path/bar.h
+  StartPos:
+    line: 0
+    character: 0
+  EndPos:
+    line: 0
+    character: 1
 CompletionLabel:    'Foo2-label'
 CompletionFilterText:    'filter'
 CompletionPlainInsertText:    'plain'
Index: clangd/index/SymbolYAML.cpp
===================================================================
--- clangd/index/SymbolYAML.cpp
+++ clangd/index/SymbolYAML.cpp
@@ -43,11 +43,20 @@
   std::string HexString;
 };
 
+template <> struct MappingTraits<SymbolLocation::Position> {
+  static void mapping(IO &io, SymbolLocation::Position &Pos) {
+    io.mapRequired("line", Pos.Line);
+    io.mapRequired("character", Pos.Character);
+  }
+};
+
 template <> struct MappingTraits<SymbolLocation> {
   static void mapping(IO &IO, SymbolLocation &Value) {
     IO.mapRequired("StartOffset", Value.StartOffset);
     IO.mapRequired("EndOffset", Value.EndOffset);
     IO.mapRequired("FileURI", Value.FileURI);
+    IO.mapRequired("StartPos", Value.StartPos);
+    IO.mapRequired("EndPos", Value.EndPos);
   }
 };
 
Index: clangd/index/SymbolCollector.cpp
===================================================================
--- clangd/index/SymbolCollector.cpp
+++ clangd/index/SymbolCollector.cpp
@@ -193,8 +193,18 @@
   SymbolLocation Result;
   Result.FileURI = FileURIStorage;
   Result.StartOffset = SM.getFileOffset(NameLoc);
-  Result.EndOffset = Result.StartOffset + clang::Lexer::MeasureTokenLength(
-                                              NameLoc, SM, LangOpts);
+  auto TokenLength = clang::Lexer::MeasureTokenLength(NameLoc, SM, LangOpts);
+  Result.EndOffset = Result.StartOffset + TokenLength;
+
+  auto FileIdAndOffset = SM.getDecomposedLoc(NameLoc);
+  auto FileId = FileIdAndOffset.first;
+  auto Offset = FileIdAndOffset.second;
+  // LSP is 0-based while source location is 1-based.
+  Result.StartPos.Line = SM.getLineNumber(FileId, Offset) - 1;
+  Result.StartPos.Character = SM.getColumnNumber(FileId, Offset) - 1;
+  Result.EndPos.Line = Result.StartPos.Line;
+  Result.EndPos.Character = Result.StartPos.Character + TokenLength;
+
   return std::move(Result);
 }
 
Index: clangd/index/Index.h
===================================================================
--- clangd/index/Index.h
+++ clangd/index/Index.h
@@ -24,13 +24,26 @@
 namespace clangd {
 
 struct SymbolLocation {
+  struct Position {
+    // Line position in a document (zero-based).
+    int Line = 0;
+
+    // Character offset on a line in a document (zero-based).
+    int Character = 0;
+  };
+
   // The URI of the source file where a symbol occurs.
   llvm::StringRef FileURI;
   // The 0-based offsets of the symbol from the beginning of the source file,
   // using half-open range, [StartOffset, EndOffset).
+  // FIXME(hokein): remove these fields in favor of Position.
   unsigned StartOffset = 0;
   unsigned EndOffset = 0;
 
+  /// The symbol range, using half-open range [StartPos, EndPos).
+  Position StartPos;
+  Position EndPos;
+
   operator bool() const { return !FileURI.empty(); }
 };
 llvm::raw_ostream &operator<<(llvm::raw_ostream &, const SymbolLocation &);
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to