[clang-tools-extra] r371976 - Implement semantic selections.
Utkarsh Saxena via cfe-commits
cfe-commits at lists.llvm.org
Mon Sep 16 04:29:35 PDT 2019
Author: usaxena95
Date: Mon Sep 16 04:29:35 2019
New Revision: 371976
URL: http://llvm.org/viewvc/llvm-project?rev=371976&view=rev
Log:
Implement semantic selections.
Summary:
For a given cursor position, it returns ranges that are interesting to the user.
Currently the semantic ranges correspond to the nodes of the syntax trees.
Subscribers: mgorny, jkorous, arphaman, kadircet, cfe-commits
Tags: #clang
Differential Revision: https://reviews.llvm.org/D67358
Added:
clang-tools-extra/trunk/clangd/SemanticSelection.cpp
clang-tools-extra/trunk/clangd/SemanticSelection.h
clang-tools-extra/trunk/clangd/unittests/SemanticSelectionTests.cpp
Modified:
clang-tools-extra/trunk/clangd/CMakeLists.txt
clang-tools-extra/trunk/clangd/unittests/CMakeLists.txt
Modified: clang-tools-extra/trunk/clangd/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clangd/CMakeLists.txt?rev=371976&r1=371975&r2=371976&view=diff
==============================================================================
--- clang-tools-extra/trunk/clangd/CMakeLists.txt (original)
+++ clang-tools-extra/trunk/clangd/CMakeLists.txt Mon Sep 16 04:29:35 2019
@@ -66,6 +66,7 @@ add_clang_library(clangDaemon
RIFF.cpp
Selection.cpp
SemanticHighlighting.cpp
+ SemanticSelection.cpp
SourceCode.cpp
QueryDriverDatabase.cpp
Threading.cpp
Added: clang-tools-extra/trunk/clangd/SemanticSelection.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clangd/SemanticSelection.cpp?rev=371976&view=auto
==============================================================================
--- clang-tools-extra/trunk/clangd/SemanticSelection.cpp (added)
+++ clang-tools-extra/trunk/clangd/SemanticSelection.cpp Mon Sep 16 04:29:35 2019
@@ -0,0 +1,64 @@
+//===--- 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/AST/DeclBase.h"
+#include "clang/Basic/SourceLocation.h"
+#include "llvm/Support/Error.h"
+
+namespace clang {
+namespace clangd {
+namespace {
+// Adds Range \p R to the Result if it is distinct from the last added Range.
+// Assumes that only consecutive ranges can coincide.
+void addIfDistinct(const Range &R, std::vector<Range> &Result) {
+ if (Result.empty() || Result.back() != R) {
+ Result.push_back(R);
+ }
+}
+} // namespace
+
+llvm::Expected<std::vector<Range>> getSemanticRanges(ParsedAST &AST,
+ Position Pos) {
+ std::vector<Range> 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) {
+ return Offset.takeError();
+ }
+
+ // Get node under the cursor.
+ SelectionTree ST(AST.getASTContext(), AST.getTokens(), *Offset);
+ for (const auto *Node = ST.commonAncestor(); Node != nullptr;
+ Node = Node->Parent) {
+ if (const Decl *D = Node->ASTNode.get<Decl>()) {
+ if (llvm::isa<TranslationUnitDecl>(D)) {
+ break;
+ }
+ }
+
+ auto SR = toHalfOpenFileRange(SM, LangOpts, Node->ASTNode.getSourceRange());
+ if (!SR.hasValue() || SM.getFileID(SR->getBegin()) != SM.getMainFileID()) {
+ continue;
+ }
+ Range R;
+ R.start = sourceLocToPosition(SM, SR->getBegin());
+ R.end = sourceLocToPosition(SM, SR->getEnd());
+ addIfDistinct(R, Result);
+ }
+ return Result;
+}
+
+} // namespace clangd
+} // namespace clang
Added: clang-tools-extra/trunk/clangd/SemanticSelection.h
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clangd/SemanticSelection.h?rev=371976&view=auto
==============================================================================
--- clang-tools-extra/trunk/clangd/SemanticSelection.h (added)
+++ clang-tools-extra/trunk/clangd/SemanticSelection.h Mon Sep 16 04:29:35 2019
@@ -0,0 +1,32 @@
+//===--- 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 "llvm/Support/Error.h"
+#include <vector>
+namespace clang {
+namespace clangd {
+
+/// Returns the list of all interesting ranges around the Position \p Pos.
+/// The interesting ranges corresponds to the AST nodes in the SelectionTree
+/// containing \p Pos.
+/// Any range in the result strictly contains all the previous ranges in the
+/// result. front() is the inner most range. back() is the outermost range.
+llvm::Expected<std::vector<Range>> getSemanticRanges(ParsedAST &AST,
+ Position Pos);
+} // namespace clangd
+} // namespace clang
+
+#endif // LLVM_CLANG_TOOLS_EXTRA_CLANGD_SEMANTICSELECTION_H
Modified: clang-tools-extra/trunk/clangd/unittests/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clangd/unittests/CMakeLists.txt?rev=371976&r1=371975&r2=371976&view=diff
==============================================================================
--- clang-tools-extra/trunk/clangd/unittests/CMakeLists.txt (original)
+++ clang-tools-extra/trunk/clangd/unittests/CMakeLists.txt Mon Sep 16 04:29:35 2019
@@ -56,6 +56,7 @@ add_unittest(ClangdUnitTests ClangdTests
RIFFTests.cpp
SelectionTests.cpp
SemanticHighlightingTests.cpp
+ SemanticSelectionTests.cpp
SerializationTests.cpp
SourceCodeTests.cpp
SymbolCollectorTests.cpp
Added: clang-tools-extra/trunk/clangd/unittests/SemanticSelectionTests.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clangd/unittests/SemanticSelectionTests.cpp?rev=371976&view=auto
==============================================================================
--- clang-tools-extra/trunk/clangd/unittests/SemanticSelectionTests.cpp (added)
+++ clang-tools-extra/trunk/clangd/unittests/SemanticSelectionTests.cpp Mon Sep 16 04:29:35 2019
@@ -0,0 +1,143 @@
+//===-- 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 "llvm/Support/Error.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]] + 34]])]]]];]]
+ }]]]]
+ )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 in between spaces.
+ 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",
+ R"cpp( // Inside struct.
+ struct A { static int a(); };
+ [[struct B {
+ [[static int b() [[{
+ [[return [[[[1^1]] + 2]]]];
+ }]]]]
+ }]];
+ )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();
+ EXPECT_THAT(llvm::cantFail(getSemanticRanges(AST, T.point())),
+ ElementsAreArray(T.ranges()))
+ << Test;
+ }
+}
+} // namespace
+} // namespace clangd
+} // namespace clang
More information about the cfe-commits
mailing list