usaxena95 updated this revision to Diff 219386.
usaxena95 added a comment.

Create range only if it represents a valid file range.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D67358/new/

https://reviews.llvm.org/D67358

Files:
  clang-tools-extra/clangd/CMakeLists.txt
  clang-tools-extra/clangd/SemanticSelection.cpp
  clang-tools-extra/clangd/SemanticSelection.h
  clang-tools-extra/clangd/unittests/CMakeLists.txt
  clang-tools-extra/clangd/unittests/SemanticSelectionTests.cpp

Index: clang-tools-extra/clangd/unittests/SemanticSelectionTests.cpp
===================================================================
--- /dev/null
+++ clang-tools-extra/clangd/unittests/SemanticSelectionTests.cpp
@@ -0,0 +1,133 @@
+//===-- SemanticSelectionTests.cpp  ----------------*- C++ -*--------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "Annotations.h"
+#include "Matchers.h"
+#include "Protocol.h"
+#include "SemanticSelection.h"
+#include "SourceCode.h"
+#include "TestTU.h"
+#include "clang/Basic/SourceLocation.h"
+#include "clang/Basic/SourceManager.h"
+#include "gmock/gmock.h"
+#include "gtest/gtest.h"
+#include <vector>
+namespace clang {
+namespace clangd {
+namespace {
+using ::testing::ElementsAreArray;
+
+TEST(SemanticSelection, All) {
+  const char *Tests[] = {
+      R"cpp( // Single statement in a function body.
+        [[void func() [[{
+          [[[[int v = [[1^00]]]];]]
+        }]]]]
+      )cpp",
+      R"cpp( // Expression
+        [[void func() [[{
+          int a = 1;
+          // int v = (10 + 2) * (a + a);
+          [[[[int v = [[[[([[[[10^]] + 2]])]] * (a + a)]]]];]]
+        }]]]]
+      )cpp",
+      R"cpp( // Function call.
+        int add(int x, int y) { return x + y; }
+        [[void callee() [[{
+          // int res = add(11, 22);
+          [[[[int res = [[add([[1^1]], 22)]]]];]]
+        }]]]]
+      )cpp",
+      R"cpp( // Tricky macros.
+        #define MUL ) * (
+        [[void func() [[{
+          // int var = (4 + 15 MUL 6 + 10);
+          [[[[int var = [[([[4 + [[1^5]]]] MUL 6 + 10)]]]];]]
+        }]]]]
+       )cpp",
+      R"cpp( // Cursor inside a macro.
+        #define HASH(x) ((x) % 10)
+        [[void func() [[{
+          [[[[int a = HASH(2^3)]];]]
+        }]]]]
+       )cpp",
+      R"cpp( // Cursor on a macro.
+        #define HASH(x) ((x) % 10)
+        [[void func() [[{
+          [[[[int a = HA^SH(23)]];]]
+        }]]]]
+       )cpp",
+      R"cpp( // Multiple declaration.
+        [[void func() [[{
+          [[[[int var1, var^2]], var3;]]
+        }]]]]
+       )cpp",
+      R"cpp( // Before comment.
+        [[void func() [[{
+          int var1 = 1;
+          [[[[int var2 = [[[[var1]]^ /*some comment*/ + 41]]]];]]
+        }]]]]
+       )cpp",
+      // Empty file.
+      "^",
+      // FIXME: We should get the whole DeclStmt as a range.
+      R"cpp( // Single statement in TU.
+        [[int v = [[1^00]]]];
+      )cpp",
+      // FIXME: No node found associated to the position.
+      R"cpp( // Cursor at end of VarDecl.
+        void func() {
+          int v = 100 + 100^;
+        }
+      )cpp",
+      // FIXME: No node found associated to the position.
+      R"cpp( // Cursor at end of VarDecl.
+        void func() {
+          int v = 100 + ^  100;
+        }
+      )cpp",
+      // Structs.
+      R"cpp(
+        struct AAA { struct BBB { static int ccc(); };};
+        [[void func() [[{
+          // int x = AAA::BBB::ccc();
+          [[[[int x = [[[[AAA::BBB::c^cc]]()]]]];]]
+        }]]]]
+      )cpp",
+      R"cpp(
+        struct AAA { struct BBB { static int ccc(); };};
+        [[void func() [[{
+          // int x = AAA::BBB::ccc();
+          [[[[int x = [[[[[[[[[[AA^A]]::]]BBB::]]ccc]]()]]]];]]
+        }]]]]
+      )cpp",
+      // Namespaces.
+      R"cpp( 
+        [[namespace nsa { 
+          [[namespace nsb { 
+            static int ccc();
+            [[void func() [[{
+              // int x = nsa::nsb::ccc();
+              [[[[int x = [[[[nsa::nsb::cc^c]]()]]]];]]
+            }]]]]
+          }]]
+        }]]
+      )cpp",
+
+  };
+
+  for (const char *Test : Tests) {
+    auto T = Annotations(Test);
+    auto AST = TestTU::withCode(T.code()).build();
+    auto Ranges = getSemanticRanges(AST, T.point()).Ranges;
+    EXPECT_THAT(Ranges, ElementsAreArray(T.ranges())) << Test;
+  }
+}
+} // namespace
+} // namespace clangd
+} // namespace clang
\ No newline at end of file
Index: clang-tools-extra/clangd/unittests/CMakeLists.txt
===================================================================
--- clang-tools-extra/clangd/unittests/CMakeLists.txt
+++ clang-tools-extra/clangd/unittests/CMakeLists.txt
@@ -56,6 +56,7 @@
   RIFFTests.cpp
   SelectionTests.cpp
   SemanticHighlightingTests.cpp
+  SemanticSelectionTests.cpp
   SerializationTests.cpp
   SourceCodeTests.cpp
   SymbolCollectorTests.cpp
Index: clang-tools-extra/clangd/SemanticSelection.h
===================================================================
--- /dev/null
+++ clang-tools-extra/clangd/SemanticSelection.h
@@ -0,0 +1,33 @@
+//===--- SemanticSelection.h -------------------------------------*- C++-*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// Features for giving interesting semantic ranges around the cursor. 
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANGD_SEMANTICSELECTION_H
+#define LLVM_CLANG_TOOLS_EXTRA_CLANGD_SEMANTICSELECTION_H
+#include "ParsedAST.h"
+#include "Protocol.h"
+#include <vector>
+namespace clang {
+namespace clangd {
+
+struct SemanticSelectionResult {
+  // The list of interesting selections around the cursor. 
+  std::vector<Range> Ranges;
+};
+
+// Returns the list of all interesting ranges around the Position \p Pos. 
+// Constructs the 
+// Any range in the result strictly contains all the previous ranges in the result.
+SemanticSelectionResult getSemanticRanges(ParsedAST &AST, Position Pos);
+} // namespace clangd
+} // namespace clang
+
+#endif // LLVM_CLANG_TOOLS_EXTRA_CLANGD_SEMANTICSELECTION_H
\ No newline at end of file
Index: clang-tools-extra/clangd/SemanticSelection.cpp
===================================================================
--- /dev/null
+++ clang-tools-extra/clangd/SemanticSelection.cpp
@@ -0,0 +1,59 @@
+//===--- SemanticSelection.cpp -----------------------------------*- C++-*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+#include "SemanticSelection.h"
+#include "ParsedAST.h"
+#include "Protocol.h"
+#include "Selection.h"
+#include "SourceCode.h"
+#include "clang/Basic/SourceLocation.h"
+
+namespace clang {
+namespace clangd {
+namespace {
+void addIfUnique(const Range &R, SemanticSelectionResult *Result) {
+  if (Result->Ranges.empty() || Result->Ranges.back() != R) {
+    Result->Ranges.push_back(R);
+  }
+}
+} // namespace
+
+SemanticSelectionResult getSemanticRanges(ParsedAST &AST, Position Pos) {
+  SemanticSelectionResult Result;
+  const auto &SM = AST.getSourceManager();
+  const auto &LangOpts = AST.getASTContext().getLangOpts();
+
+  auto FID = SM.getMainFileID();
+  auto Offset = positionToOffset(SM.getBufferData(FID), Pos);
+  if (!Offset) {
+    llvm::errs() << "Unable to convert postion to offset";
+    return {};
+  }
+
+  // Get node under the cursor.
+  SelectionTree ST(AST.getASTContext(), AST.getTokens(), *Offset);
+  for (const auto *Node = ST.commonAncestor(); Node != nullptr;
+       Node = Node->Parent) {
+    auto SR = Node->ASTNode.getSourceRange();
+    if (SR.isInvalid()) {
+      continue;
+    }
+    SourceLocation BeginLoc = SR.getBegin();
+    SourceLocation EndLoc =
+        Lexer::getLocForEndOfToken(SR.getEnd(), 0, SM, LangOpts);
+    if (isValidFileRange(SM, {BeginLoc, EndLoc})) {
+      Range R;
+      R.start = sourceLocToPosition(SM, BeginLoc);
+      R.end = sourceLocToPosition(SM, EndLoc);
+      addIfUnique(R, &Result);
+    }
+  }
+  return Result;
+}
+
+} // namespace clangd
+} // namespace clang
\ No newline at end of file
Index: clang-tools-extra/clangd/CMakeLists.txt
===================================================================
--- clang-tools-extra/clangd/CMakeLists.txt
+++ clang-tools-extra/clangd/CMakeLists.txt
@@ -66,6 +66,7 @@
   RIFF.cpp
   Selection.cpp
   SemanticHighlighting.cpp
+  SemanticSelection.cpp
   SourceCode.cpp
   QueryDriverDatabase.cpp
   Threading.cpp
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to