[clang] 21750a1 - [clang][ExtractAPI] Refactor ExtractAPIVisitor to make it more extensible
Daniel Grumberg via cfe-commits
cfe-commits at lists.llvm.org
Mon Mar 27 09:24:33 PDT 2023
Author: Daniel Grumberg
Date: 2023-03-27T17:24:10+01:00
New Revision: 21750a1ae8c86ffefc72f115116c80a98a0792dc
URL: https://github.com/llvm/llvm-project/commit/21750a1ae8c86ffefc72f115116c80a98a0792dc
DIFF: https://github.com/llvm/llvm-project/commit/21750a1ae8c86ffefc72f115116c80a98a0792dc.diff
LOG: [clang][ExtractAPI] Refactor ExtractAPIVisitor to make it more extensible
Use CRTP to enable creating statically dispatched subclasses of
ExtractAPIVisitor.
This enables adding extension points and customising the behavior more
easily.
This is used in CXExtractAPI.cpp to create a specialized visitor for
Libclang as well as streamlining the batch implementation in ExtractAPIConsumer.cpp
[clang][ExtractAPI] Improve tests for clang_getSymbolGraphForCursor
Adds a new mode to c-index-test that can fetch a single symbol symbol
graph for a given source location. This way we can be more precise when
writing tests for clang_getSymbolGraphForCursor.
Additionaly this makes it easier to debug the function.
Differential Revision: https://reviews.llvm.org/D146656
Added:
Modified:
clang/test/Index/extract-api-cursor.m
clang/tools/c-index-test/c-index-test.c
Removed:
################################################################################
diff --git a/clang/test/Index/extract-api-cursor.m b/clang/test/Index/extract-api-cursor.m
index 078f2f52e215c..16844ca1674ee 100644
--- a/clang/test/Index/extract-api-cursor.m
+++ b/clang/test/Index/extract-api-cursor.m
@@ -1,3 +1,5 @@
+// Test is line- and column-sensitive. Run lines are below
+
/// Foo docs
struct Foo {
/// Bar docs
@@ -25,91 +27,94 @@ @interface Derived: Base
- (void)derivedMethodWithValue:(id<Protocol>)value;
@end
-/// This won't show up in docs because we can't serialize it
- at interface Derived ()
-/// Derived method in category docs, won't show up either.
-- (void)derivedMethodInCategory;
+ at implementation Derived
+- (void)derivedMethodWithValue:(id<Protocol>)value {
+ int a = 5;
+}
@end
-// RUN: c-index-test -single-symbol-sgfs local %s | FileCheck %s
-
-// Checking for Foo
-// CHECK: "parentContexts":[]
-// CHECK-SAME: "relatedSymbols":[]
-// CHECK-SAME: "relationships":[]
-// CHECK-SAME: "text":"Foo docs"
-// CHECK-SAME: "kind":{"displayName":"Structure","identifier":"objective-c.struct"}
-// CHECK-SAME: "title":"Foo"
-
-// Checking for bar
-// CHECK-NEXT: "parentContexts":[{"kind":"objective-c.struct","name":"Foo","usr":"c:@S at Foo"}]
-// CHECK-SAME: "relatedSymbols":[]
-// CHECK-SAME: "relationships":[{"kind":"memberOf","source":"c:@S at Foo@FI at bar","target":"c:@S at Foo"
-// CHECK-SAME: "text":"Bar docs"
-// CHECK-SAME: "kind":{"displayName":"Instance Property","identifier":"objective-c.property"}
-// CHECK-SAME: "title":"bar"
-
-// Checking for Base
-// CHECK-NEXT: "parentContexts":[]
-// CHECK-SAME: "relatedSymbols":[]
-// CHECK-SAME: "relationships":[]
-// CHECK-SAME: "text":"Base docs"
-// CHECK-SAME: "kind":{"displayName":"Class","identifier":"objective-c.class"}
-// CHECK-SAME: "title":"Base"
-
-// Checking for baseProperty
-// CHECK-NEXT: "parentContexts":[{"kind":"objective-c.class","name":"Base","usr":"c:objc(cs)Base"}]
-// CHECK-SAME: "relatedSymbols":[{"accessLevel":"public","declarationLanguage":"objective-c"
-// CHECK-SAME: "isSystem":false
-// CHECK-SAME: "usr":"c:@S at Foo"}]
-// CHECK-SAME: "relationships":[{"kind":"memberOf","source":"c:objc(cs)Base(py)baseProperty","target":"c:objc(cs)Base"
-// CHECK-SAME: "text":"Base property docs"
-// CHECK-SAME: "kind":{"displayName":"Instance Property","identifier":"objective-c.property"}
-// CHECK-SAME: "title":"baseProperty"
-
-// Checking for baseMethodWithArg
-// CHECK-NEXT: "parentContexts":[{"kind":"objective-c.class","name":"Base","usr":"c:objc(cs)Base"}]
-// CHECK-SAME: "relatedSymbols":[]
-// CHECK-SAME: "relationships":[{"kind":"memberOf","source":"c:objc(cs)Base(im)baseMethodWithArg:","target":"c:objc(cs)Base"
-// CHECK-SAME: "text":"Base method docs"
-// CHECK-SAME: "kind":{"displayName":"Instance Method","identifier":"objective-c.method"}
-// CHECK-SAME: "title":"baseMethodWithArg:"
-
-// Checking for Protocol
-// CHECK-NEXT: "parentContexts":[]
-// CHECK-SAME: "relatedSymbols":[]
-// CHECK-SAME: "relationships":[]
-// CHECK-SAME: "text":"Protocol docs"
-// CHECK-SAME: "kind":{"displayName":"Protocol","identifier":"objective-c.protocol"}
-// CHECK-SAME: "title":"Protocol"
-
-// Checking for protocolProperty
-// CHECK-NEXT: "parentContexts":[{"kind":"objective-c.protocol","name":"Protocol","usr":"c:objc(pl)Protocol"}]
-// CHECK-SAME: "relatedSymbols":[{"accessLevel":"public","declarationLanguage":"objective-c"
-// CHECK-SAME: "isSystem":false
-// CHECK-SAME: "usr":"c:@S at Foo"}]
-// CHECK-SAME: "relationships":[{"kind":"memberOf","source":"c:objc(pl)Protocol(py)protocolProperty","target":"c:objc(pl)Protocol"
-// CHECK-SAME: "text":"Protocol property docs"
-// CHECK-SAME: "kind":{"displayName":"Instance Property","identifier":"objective-c.property"}
-// CHECK-SAME: "title":"protocolProperty"
-
-// Checking for Derived
-// CHECK-NEXT: "parentContexts":[]
-// CHECK-SAME: "relatedSymbols":[{"accessLevel":"public","declarationLanguage":"objective-c"
-// CHECK-SAME: "isSystem":false
-// CHECK-SAME: "usr":"c:objc(cs)Base"}]
-// CHECK-SAME: "relationships":[{"kind":"inheritsFrom","source":"c:objc(cs)Derived","target":"c:objc(cs)Base"
-// CHECK-SAME: "text":"Derived docs"
-// CHECK-SAME: "kind":{"displayName":"Class","identifier":"objective-c.class"}
-// CHECK-SAME: "title":"Derived"
-
-// Checking for derivedMethodWithValue
-// CHECK-NEXT: "parentContexts":[{"kind":"objective-c.class","name":"Derived","usr":"c:objc(cs)Derived"}]
-// CHECK-SAME: "relatedSymbols":[]
-// CHECK-SAME: "relationships":[{"kind":"memberOf","source":"c:objc(cs)Derived(im)derivedMethodWithValue:","target":"c:objc(cs)Derived"
-// CHECK-SAME: "text":"Derived method docs"
-// CHECK-SAME: "kind":{"displayName":"Instance Method","identifier":"objective-c.method"}
-// CHECK-SAME: "title":"derivedMethodWithValue:"
-
-// CHECK-NOT: This won't show up in docs because we can't serialize it
-// CHECK-NOT: Derived method in category docs, won't show up either.
+// RUN: c-index-test -single-symbol-sgf-at=%s:4:9 local %s | FileCheck -check-prefix=CHECK-FOO %s
+// CHECK-FOO: "parentContexts":[]
+// CHECK-FOO: "relatedSymbols":[]
+// CHECK-FOO: "relationships":[]
+// CHECK-FOO: "text":"Foo docs"
+// CHECK-FOO: "kind":{"displayName":"Structure","identifier":"objective-c.struct"}
+// CHECK-FOO: "title":"Foo"
+
+// RUN: c-index-test -single-symbol-sgf-at=%s:6:9 local %s | FileCheck -check-prefix=CHECK-BAR %s
+// CHECK-BAR: "parentContexts":[{"kind":"objective-c.struct","name":"Foo","usr":"c:@S at Foo"}]
+// CHECK-BAR: "relatedSymbols":[]
+// CHECK-BAR: "relationships":[{"kind":"memberOf","source":"c:@S at Foo@FI at bar","target":"c:@S at Foo"
+// CHECK-BAR: "text":"Bar docs"
+// CHECK-BAR: "kind":{"displayName":"Instance Property","identifier":"objective-c.property"}
+// CHECK-BAR: "title":"bar"
+
+// RUN: c-index-test -single-symbol-sgf-at=%s:10:11 local %s | FileCheck -check-prefix=CHECK-BASE %s
+// CHECK-BASE: "parentContexts":[]
+// CHECK-BASE: "relatedSymbols":[]
+// CHECK-BASE: "relationships":[]
+// CHECK-BASE: "text":"Base docs"
+// CHECK-BASE: "kind":{"displayName":"Class","identifier":"objective-c.class"}
+// CHECK-BASE: "title":"Base"
+
+// RUN: c-index-test -single-symbol-sgf-at=%s:12:25 local %s | FileCheck -check-prefix=CHECK-BASE-PROP %s
+// CHECK-BASE-PROP: "parentContexts":[{"kind":"objective-c.class","name":"Base","usr":"c:objc(cs)Base"}]
+// CHECK-BASE-PROP: "relatedSymbols":[{"accessLevel":"public","declarationLanguage":"objective-c"
+// CHECK-BASE-PROP: "isSystem":false
+// CHECK-BASE-PROP: "usr":"c:@S at Foo"}]
+// CHECK-BASE-PROP: "relationships":[{"kind":"memberOf","source":"c:objc(cs)Base(py)baseProperty","target":"c:objc(cs)Base"
+// CHECK-BASE-PROP: "text":"Base property docs"
+// CHECK-BASE-PROP: "kind":{"displayName":"Instance Property","identifier":"objective-c.property"}
+// CHECK-BASE-PROP: "title":"baseProperty"
+
+// RUN: c-index-test -single-symbol-sgf-at=%s:15:9 local %s | FileCheck -check-prefix=CHECK-BASE-METHOD %s
+// CHECK-BASE-METHOD: "parentContexts":[{"kind":"objective-c.class","name":"Base","usr":"c:objc(cs)Base"}]
+// CHECK-BASE-METHOD: "relatedSymbols":[]
+// CHECK-BASE-METHOD: "relationships":[{"kind":"memberOf","source":"c:objc(cs)Base(im)baseMethodWithArg:","target":"c:objc(cs)Base"
+// CHECK-BASE-METHOD: "text":"Base method docs"
+// CHECK-BASE-METHOD: "kind":{"displayName":"Instance Method","identifier":"objective-c.method"}
+// CHECK-BASE-METHOD: "title":"baseMethodWithArg:"
+
+// RUN: c-index-test -single-symbol-sgf-at=%s:19:11 local %s | FileCheck -check-prefix=CHECK-PROTOCOL %s
+// CHECK-PROTOCOL: "parentContexts":[]
+// CHECK-PROTOCOL: "relatedSymbols":[]
+// CHECK-PROTOCOL: "relationships":[]
+// CHECK-PROTOCOL: "text":"Protocol docs"
+// CHECK-PROTOCOL: "kind":{"displayName":"Protocol","identifier":"objective-c.protocol"}
+// CHECK-PROTOCOL: "title":"Protocol"
+
+// RUN: c-index-test -single-symbol-sgf-at=%s:21:27 local %s | FileCheck -check-prefix=CHECK-PROTOCOL-PROP %s
+// CHECK-PROTOCOL-PROP: "parentContexts":[{"kind":"objective-c.protocol","name":"Protocol","usr":"c:objc(pl)Protocol"}]
+// CHECK-PROTOCOL-PROP: "relatedSymbols":[{"accessLevel":"public","declarationLanguage":"objective-c"
+// CHECK-PROTOCOL-PROP: "isSystem":false
+// CHECK-PROTOCOL-PROP: "usr":"c:@S at Foo"}]
+// CHECK-PROTOCOL-PROP: "relationships":[{"kind":"memberOf","source":"c:objc(pl)Protocol(py)protocolProperty","target":"c:objc(pl)Protocol"
+// CHECK-PROTOCOL-PROP: "text":"Protocol property docs"
+// CHECK-PROTOCOL-PROP: "kind":{"displayName":"Instance Property","identifier":"objective-c.property"}
+// CHECK-PROTOCOL-PROP: "title":"protocolProperty"
+
+// RUN: c-index-test -single-symbol-sgf-at=%s:25:15 local %s | FileCheck -check-prefix=CHECK-DERIVED %s
+// CHECK-DERIVED: "parentContexts":[]
+// CHECK-DERIVED: "relatedSymbols":[{"accessLevel":"public","declarationLanguage":"objective-c"
+// CHECK-DERIVED: "isSystem":false
+// CHECK-DERIVED: "usr":"c:objc(cs)Base"}]
+// CHECK-DERIVED: "relationships":[{"kind":"inheritsFrom","source":"c:objc(cs)Derived","target":"c:objc(cs)Base"
+// CHECK-DERIVED: "text":"Derived docs"
+// CHECK-DERIVED: "kind":{"displayName":"Class","identifier":"objective-c.class"}
+// CHECK-DERIVED: "title":"Derived"
+
+// RUN: c-index-test -single-symbol-sgf-at=%s:27:11 local %s | FileCheck -check-prefix=CHECK-DERIVED-METHOD %s
+// CHECK-DERIVED-METHOD: "parentContexts":[{"kind":"objective-c.class","name":"Derived","usr":"c:objc(cs)Derived"}]
+// CHECK-DERIVED-METHOD: "relatedSymbols":[]
+// CHECK-DERIVED-METHOD: "relationships":[{"kind":"memberOf","source":"c:objc(cs)Derived(im)derivedMethodWithValue:","target":"c:objc(cs)Derived"
+// CHECK-DERIVED-METHOD: "text":"Derived method docs"
+// CHECK-DERIVED-METHOD: "kind":{"displayName":"Instance Method","identifier":"objective-c.method"}
+// CHECK-DERIVED-METHOD: "title":"derivedMethodWithValue:"
+
+// RUN: c-index-test -single-symbol-sgf-at=%s:31:11 local %s | FileCheck -check-prefix=CHECK-DERIVED-METHOD-IMPL %s
+// CHECK-DERIVED-METHOD-IMPL: "parentContexts":[{"kind":"objective-c.class","name":"Derived","usr":"c:objc(cs)Derived"}]
+// CHECK-DERIVED-METHOD-IMPL: "relatedSymbols":[]
+// CHECK-DERIVED-METHOD-IMPL: "relationships":[{"kind":"memberOf","source":"c:objc(cs)Derived(im)derivedMethodWithValue:","target":"c:objc(cs)Derived"
+// CHECK-DERIVED-METHOD-IMPL: "text":"Derived method docs"
+// CHECK-DERIVED-METHOD-IMPL: "kind":{"displayName":"Instance Method","identifier":"objective-c.method"}
+// CHECK-DERIVED-METHOD-IMPL: "title":"derivedMethodWithValue:"
diff --git a/clang/tools/c-index-test/c-index-test.c b/clang/tools/c-index-test/c-index-test.c
index 448435e83027c..f116111ffacec 100644
--- a/clang/tools/c-index-test/c-index-test.c
+++ b/clang/tools/c-index-test/c-index-test.c
@@ -3,6 +3,7 @@
#include "clang-c/BuildSystem.h"
#include "clang-c/CXCompilationDatabase.h"
#include "clang-c/CXErrorCode.h"
+#include "clang-c/CXSourceLocation.h"
#include "clang-c/CXString.h"
#include "clang-c/Documentation.h"
#include "clang-c/Index.h"
@@ -4881,6 +4882,21 @@ static int perform_test_single_symbol_sgf(const char *input, int argc,
return result;
}
+static void inspect_single_symbol_sgf_cursor(CXCursor Cursor) {
+ CXSourceLocation CursorLoc;
+ CXString SGFData;
+ const char *SGF;
+ unsigned line, column;
+ CursorLoc = clang_getCursorLocation(Cursor);
+ clang_getSpellingLocation(CursorLoc, 0, &line, &column, 0);
+ printf("%d:%d: ", line, column);
+
+ SGFData = clang_getSymbolGraphForCursor(Cursor);
+ SGF = clang_getCString(SGFData);
+ if (SGF)
+ printf("%s\n", SGF);
+}
+
/******************************************************************************/
/* Command line processing. */
/******************************************************************************/
@@ -4940,6 +4956,7 @@ static void print_usage(void) {
" c-index-test -print-usr-file <file>\n");
fprintf(stderr,
" c-index-test -single-symbol-sgfs <symbol filter> {<args>*}\n"
+ " c-index-test -single-symbol-sgf-at=<site> {<args>*}\n"
" c-index-test -single-symbol-sgf-for=<usr> {<args>}*\n");
fprintf(stderr,
" c-index-test -write-pch <file> <compiler arguments>\n"
@@ -5076,6 +5093,9 @@ int cindextest_main(int argc, const char **argv) {
else if (argc > 3 && strcmp(argv[1], "-single-symbol-sgfs") == 0)
return perform_test_load_source(argc - 3, argv + 3, argv[2],
PrintSingleSymbolSGFs, NULL);
+ else if (argc > 2 && strstr(argv[1], "-single-symbol-sgf-at=") == argv[1])
+ return inspect_cursor_at(
+ argc, argv, "-single-symbol-sgf-at=", inspect_single_symbol_sgf_cursor);
else if (argc > 2 && strstr(argv[1], "-single-symbol-sgf-for=") == argv[1])
return perform_test_single_symbol_sgf(argv[1], argc - 2, argv + 2);
More information about the cfe-commits
mailing list