kadircet created this revision.
kadircet added a reviewer: sammccall.
Herald added a project: All.
kadircet requested review of this revision.
Herald added subscribers: cfe-commits, ilya-biryukov.
Herald added a project: clang.

Dotdots were removed only when converting a relative path to absolute
one. This patch makes the behaviour consistent for absolute file paths by
removing them in that case as well. Also updates the documentation to mention
the behaviour.

Fixes https://github.com/clangd/clangd/issues/1317


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D137962

Files:
  clang/docs/JSONCompilationDatabase.rst
  clang/lib/Tooling/JSONCompilationDatabase.cpp
  clang/unittests/Tooling/CompilationDatabaseTest.cpp


Index: clang/unittests/Tooling/CompilationDatabaseTest.cpp
===================================================================
--- clang/unittests/Tooling/CompilationDatabaseTest.cpp
+++ clang/unittests/Tooling/CompilationDatabaseTest.cpp
@@ -92,16 +92,32 @@
   expected_files.push_back(std::string(PathStorage.str()));
   llvm::sys::path::native("//net/file1", PathStorage);
   expected_files.push_back(std::string(PathStorage.str()));
+  llvm::sys::path::native("//net/dir/file3", PathStorage);
+  expected_files.push_back(std::string(PathStorage.str()));
   EXPECT_EQ(expected_files,
-            getAllFiles("[{\"directory\":\"//net/dir\","
-                        "\"command\":\"command\","
-                        "\"file\":\"file1\"},"
-                        " {\"directory\":\"//net/dir\","
-                        "\"command\":\"command\","
-                        "\"file\":\"../file1\"},"
-                        " {\"directory\":\"//net/dir\","
-                        "\"command\":\"command\","
-                        "\"file\":\"file2\"}]",
+            getAllFiles(R"json(
+            [
+              {
+                "directory": "//net/dir",
+                "command": "command",
+                "file": "file1"
+              },
+              {
+                "directory": "//net/dir",
+                "command": "command",
+                "file": "../file1"
+              },
+              {
+                "directory": "//net/dir",
+                "command": "command",
+                "file": "file2"
+              },
+              {
+                "directory": "//net/dir",
+                "command": "command",
+                "file": "//net/dir/foo/../file3"
+              }
+            ])json",
                         ErrorMessage, JSONCommandLineSyntax::Gnu))
       << ErrorMessage;
 }
Index: clang/lib/Tooling/JSONCompilationDatabase.cpp
===================================================================
--- clang/lib/Tooling/JSONCompilationDatabase.cpp
+++ clang/lib/Tooling/JSONCompilationDatabase.cpp
@@ -426,6 +426,7 @@
       llvm::sys::path::native(AbsolutePath, NativeFilePath);
     } else {
       llvm::sys::path::native(FileName, NativeFilePath);
+      llvm::sys::path::remove_dots(NativeFilePath, /*remove_dot_dot=*/ true);
     }
     auto Cmd = CompileCommandRef(Directory, File, *Command, Output);
     IndexByFile[NativeFilePath].push_back(Cmd);
Index: clang/docs/JSONCompilationDatabase.rst
===================================================================
--- clang/docs/JSONCompilationDatabase.rst
+++ clang/docs/JSONCompilationDatabase.rst
@@ -86,7 +86,8 @@
    compilation step. This is used by tools as the key into the
    compilation database. There can be multiple command objects for the
    same file, for example if the same source file is compiled with
-   different configurations.
+   different configurations. ``dot`` (./) ``dotdot`` (../) in the path is
+   stripped lexically.
 -  **arguments:** The compile command argv as list of strings.
    This should run the compilation step for the translation unit ``file``.
    ``arguments[0]`` should be the executable name, such as ``clang++``.


Index: clang/unittests/Tooling/CompilationDatabaseTest.cpp
===================================================================
--- clang/unittests/Tooling/CompilationDatabaseTest.cpp
+++ clang/unittests/Tooling/CompilationDatabaseTest.cpp
@@ -92,16 +92,32 @@
   expected_files.push_back(std::string(PathStorage.str()));
   llvm::sys::path::native("//net/file1", PathStorage);
   expected_files.push_back(std::string(PathStorage.str()));
+  llvm::sys::path::native("//net/dir/file3", PathStorage);
+  expected_files.push_back(std::string(PathStorage.str()));
   EXPECT_EQ(expected_files,
-            getAllFiles("[{\"directory\":\"//net/dir\","
-                        "\"command\":\"command\","
-                        "\"file\":\"file1\"},"
-                        " {\"directory\":\"//net/dir\","
-                        "\"command\":\"command\","
-                        "\"file\":\"../file1\"},"
-                        " {\"directory\":\"//net/dir\","
-                        "\"command\":\"command\","
-                        "\"file\":\"file2\"}]",
+            getAllFiles(R"json(
+            [
+              {
+                "directory": "//net/dir",
+                "command": "command",
+                "file": "file1"
+              },
+              {
+                "directory": "//net/dir",
+                "command": "command",
+                "file": "../file1"
+              },
+              {
+                "directory": "//net/dir",
+                "command": "command",
+                "file": "file2"
+              },
+              {
+                "directory": "//net/dir",
+                "command": "command",
+                "file": "//net/dir/foo/../file3"
+              }
+            ])json",
                         ErrorMessage, JSONCommandLineSyntax::Gnu))
       << ErrorMessage;
 }
Index: clang/lib/Tooling/JSONCompilationDatabase.cpp
===================================================================
--- clang/lib/Tooling/JSONCompilationDatabase.cpp
+++ clang/lib/Tooling/JSONCompilationDatabase.cpp
@@ -426,6 +426,7 @@
       llvm::sys::path::native(AbsolutePath, NativeFilePath);
     } else {
       llvm::sys::path::native(FileName, NativeFilePath);
+      llvm::sys::path::remove_dots(NativeFilePath, /*remove_dot_dot=*/ true);
     }
     auto Cmd = CompileCommandRef(Directory, File, *Command, Output);
     IndexByFile[NativeFilePath].push_back(Cmd);
Index: clang/docs/JSONCompilationDatabase.rst
===================================================================
--- clang/docs/JSONCompilationDatabase.rst
+++ clang/docs/JSONCompilationDatabase.rst
@@ -86,7 +86,8 @@
    compilation step. This is used by tools as the key into the
    compilation database. There can be multiple command objects for the
    same file, for example if the same source file is compiled with
-   different configurations.
+   different configurations. ``dot`` (./) ``dotdot`` (../) in the path is
+   stripped lexically.
 -  **arguments:** The compile command argv as list of strings.
    This should run the compilation step for the translation unit ``file``.
    ``arguments[0]`` should be the executable name, such as ``clang++``.
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to