Skip to content

Commit 32c305f

Browse files
authored
Merge pull request #71831 from ahoppen/ahoppen/raw-doc-comment
[SourceKit] Add the raw doc comment to the cursor info response
2 parents 7ed54c9 + 873ed19 commit 32c305f

21 files changed

+133
-22
lines changed

include/swift/IDE/CommentConversion.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,12 @@ bool getDocumentationCommentAsXML(
3232
const Decl *D, raw_ostream &OS,
3333
TypeOrExtensionDecl SynthesizedTarget = TypeOrExtensionDecl());
3434

35+
/// If the declaration has a documentation comment, prints the comment to \p OS
36+
/// in the form it's written in source.
37+
///
38+
/// \returns true if the declaration has a documentation comment.
39+
bool getRawDocumentationComment(const Decl *D, raw_ostream &OS);
40+
3541
/// If the declaration has a documentation comment and a localization key,
3642
/// print it into the given output stream and return true. Else, return false.
3743
bool getLocalizationKey(const Decl *D, raw_ostream &OS);

lib/IDE/CommentConversion.cpp

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
#include "llvm/Support/MemoryBuffer.h"
2525
#include "llvm/Support/raw_ostream.h"
2626
#include "clang/AST/ASTContext.h"
27+
#include "clang/AST/Comment.h"
2728
#include "clang/AST/Decl.h"
2829
#include "clang/Index/CommentToXML.h"
2930

@@ -496,6 +497,38 @@ bool ide::getDocumentationCommentAsXML(const Decl *D, raw_ostream &OS,
496497
return true;
497498
}
498499

500+
bool ide::getRawDocumentationComment(const Decl *D, raw_ostream &OS) {
501+
ClangNode MaybeClangNode = D->getClangNode();
502+
if (MaybeClangNode) {
503+
const clang::Decl *CD = MaybeClangNode.getAsDecl();
504+
if (!CD) {
505+
return false;
506+
}
507+
const clang::ASTContext &ClangContext = CD->getASTContext();
508+
const clang::comments::FullComment *FC =
509+
ClangContext.getCommentForDecl(CD, /*PP=*/nullptr);
510+
if (!FC) {
511+
return false;
512+
}
513+
const clang::RawComment *rawComment = ClangContext.getRawCommentForAnyRedecl(FC->getDecl());
514+
if (!rawComment) {
515+
return false;
516+
}
517+
OS << rawComment->getFormattedText(ClangContext.getSourceManager(),
518+
ClangContext.getDiagnostics());
519+
return true;
520+
}
521+
522+
const Decl *docD = getDocCommentProvidingDecl(D);
523+
if (!docD) {
524+
return false;
525+
}
526+
RawComment rawComment = docD->getRawComment();
527+
OS << swift::markup::MarkupContext().getLineList(rawComment).str();
528+
OS.flush();
529+
return true;
530+
}
531+
499532
bool ide::getLocalizationKey(const Decl *D, raw_ostream &OS) {
500533
swift::markup::MarkupContext MC;
501534
auto DC = getCascadingDocComment(MC, D);

lib/Markup/LineList.cpp

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -24,18 +24,19 @@ std::string LineList::str() const {
2424
if (Lines.empty())
2525
return "";
2626

27-
auto FirstLine = Lines.begin();
28-
while (FirstLine != Lines.end() && FirstLine->Text.empty())
29-
++FirstLine;
27+
Line *FirstNonEmptyLine = Lines.begin();
28+
while (FirstNonEmptyLine != Lines.end() && FirstNonEmptyLine->Text.empty())
29+
++FirstNonEmptyLine;
3030

31-
if (FirstLine == Lines.end())
31+
if (FirstNonEmptyLine == Lines.end())
3232
return "";
3333

34-
auto InitialIndentation = measureIndentation(FirstLine->Text);
34+
auto InitialIndentation = measureIndentation(FirstNonEmptyLine->Text);
3535

36-
for (auto Line = FirstLine; Line != Lines.end(); ++Line) {
36+
Stream << FirstNonEmptyLine->Text.drop_front(InitialIndentation);
37+
for (auto Line = FirstNonEmptyLine + 1; Line != Lines.end(); ++Line) {
3738
auto Drop = std::min(InitialIndentation, Line->FirstNonspaceOffset);
38-
Stream << Line->Text.drop_front(Drop) << "\n";
39+
Stream << '\n' << Line->Text.drop_front(Drop);
3940
}
4041

4142
Stream.flush();
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
/// Test
2+
/// - Returns: An integer
3+
func test() -> Int {}
4+
// RUN: %sourcekitd-test -req=cursor -pos=%(line - 1):6 %s -- %s | %FileCheck %s
5+
6+
// CHECK-LABEL: DOC COMMENT
7+
// CHECK: Test
8+
// CHECK: - Returns: An integer
9+
10+
// CHECK-LABEL: DOC COMMENT XML
11+
// CHECK: <Function file="{{.*}}" line="3" column="6"><Name>test()</Name><USR>s:18cursor_doc_comment4testSiyF</USR><Declaration>func test() -&gt; Int</Declaration><CommentParts><Abstract><Para>Test</Para></Abstract><ResultDiscussion><Para>An integer</Para></ResultDiscussion></CommentParts></Function>
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
// RUN: %empty-directory(%t)
2+
// RUN: split-file --leading-lines %s %t
3+
4+
//--- header.h
5+
6+
/// This comment contains `markup`.
7+
///
8+
/// - And a list
9+
void testCDecl();
10+
11+
//--- module.modulemap
12+
13+
module MyClangModule { header "header.h" }
14+
15+
//--- test.swift
16+
17+
import MyClangModule
18+
19+
func test() {
20+
// RUN: %sourcekitd-test -req=cursor -pos=%(line + 1):3 %s -- %s -I %t | %FileCheck %s
21+
testCDecl()
22+
}
23+
24+
// CHECK-LABEL: DOC COMMENT
25+
// CHECK: This comment contains `markup`.
26+
// CHECK: - And a list
27+
// CHECK-LABEL: DOC COMMENT XML
28+
// CHECK: <Function file="{{.*}}" line="9" column="6"><Name>testCDecl</Name><USR>c:@F@testCDecl</USR><Declaration>func testCDecl()</Declaration><Abstract><Para> This comment contains `markup`.</Para></Abstract><Discussion><Para> - And a list</Para></Discussion></Function>

test/SourceKit/CursorInfo/cursor_info.swift

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -288,6 +288,9 @@ let strInterpolation = "This is a \(stringStr + "ing") interpolation"
288288
// CHECK4-NEXT: Foo{{$}}
289289
// CHECK4-NEXT: <Declaration>var fooIntVar: <Type usr="s:s5Int32V">Int32</Type></Declaration>
290290
// CHECK4-NEXT: <decl.var.global><syntaxtype.keyword>var</syntaxtype.keyword> <decl.name>fooIntVar</decl.name>: <decl.var.type><ref.struct usr="s:s5Int32V">Int32</ref.struct></decl.var.type></decl.var.global>
291+
// CHECK4-NEXT: DOC COMMENT
292+
// CHECK4-NEXT: Aaa. fooIntVar. Bbb.
293+
// CHECK4-NEXT: DOC COMMENT XML
291294
// CHECK4-NEXT: <Variable file="{{[^"]+}}Foo.h" line="{{[0-9]+}}" column="{{[0-9]+}}"><Name>fooIntVar</Name><USR>c:@fooIntVar</USR><Declaration>var fooIntVar: Int32</Declaration><Abstract><Para> Aaa. fooIntVar. Bbb.</Para></Abstract></Variable>
292295

293296
// RUN: %sourcekitd-test -req=cursor -pos=8:7 %s -- -F %S/../Inputs/libIDE-mock-sdk -I %t.tmp %s | %FileCheck -check-prefix=CHECK5 %s
@@ -307,6 +310,9 @@ let strInterpolation = "This is a \(stringStr + "ing") interpolation"
307310
// CHECK6-NEXT: FooSwiftModule
308311
// CHECK6-NEXT: <Declaration>func fooSwiftFunc() -&gt; <Type usr="s:Si">Int</Type></Declaration>
309312
// CHECK6-NEXT: <decl.function.free><syntaxtype.keyword>func</syntaxtype.keyword> <decl.name>fooSwiftFunc</decl.name>() -&gt; <decl.function.returntype><ref.struct usr="s:Si">Int</ref.struct></decl.function.returntype></decl.function.free>
313+
// CHECK6-NEXT: DOC COMMENT
314+
// CHECK6-NEXT: This is 'fooSwiftFunc' from 'FooSwiftModule'.
315+
// CHECK6-NEXT: DOC COMMENT XML
310316
// CHECK6-NEXT: {{^}}<Function file="{{.*}}/FooSwiftModule.swift" line="2" column="13"><Name>fooSwiftFunc()</Name><USR>s:14FooSwiftModule03fooB4FuncSiyF</USR><Declaration>func fooSwiftFunc() -&gt; Int</Declaration><CommentParts><Abstract><Para>This is ‘fooSwiftFunc’ from ‘FooSwiftModule’.</Para></Abstract></CommentParts></Function>{{$}}
311317

312318
// RUN: %sourcekitd-test -req=cursor -pos=14:10 %s -- -F %S/../Inputs/libIDE-mock-sdk -I %t.tmp %s | %FileCheck -check-prefix=CHECK7 %s
@@ -319,6 +325,9 @@ let strInterpolation = "This is a \(stringStr + "ing") interpolation"
319325
// CHECK7-NEXT: cursor_info{{$}}
320326
// CHECK7-NEXT: <Declaration>struct S1</Declaration>
321327
// CHECK7-NEXT: <decl.struct><syntaxtype.keyword>struct</syntaxtype.keyword> <decl.name>S1</decl.name></decl.struct>
328+
// CHECK7-NEXT: DOC COMMENT
329+
// CHECK7-NEXT: Aaa. S1. Bbb.
330+
// CHECK7-NEXT: DOC COMMENT XML
322331
// CHECK7-NEXT: <Class file="{{[^"]+}}cursor_info.swift" line="13" column="8"><Name>S1</Name><USR>s:11cursor_info2S1V</USR><Declaration>struct S1</Declaration><CommentParts><Abstract><Para>Aaa. S1. Bbb.</Para></Abstract></CommentParts></Class>
323332

324333
// RUN: %sourcekitd-test -req=cursor -pos=19:12 %s -- -F %S/../Inputs/libIDE-mock-sdk -I %t.tmp %s | %FileCheck -check-prefix=CHECK8 %s
@@ -780,6 +789,11 @@ let strInterpolation = "This is a \(stringStr + "ing") interpolation"
780789
// CHECK87-NEXT: cursor_info{{$}}
781790
// CHECK87-NEXT: <Declaration>struct HasLocalizationKey</Declaration>
782791
// CHECK87-NEXT: <decl.struct><syntaxtype.keyword>struct</syntaxtype.keyword> <decl.name>HasLocalizationKey</decl.name></decl.struct>
792+
// CHECK87-NEXT: DOC COMMENT
793+
// CHECK87-NEXT: Brief.
794+
// CHECK87-EMPTY:
795+
// CHECK87-NEXT: - LocalizationKey: ABC
796+
// CHECK87-NEXT: DOC COMMENT XML
783797
// CHECK87-NEXT: <Class file="{{[^"]+}}cursor_info.swift" line="213" column="8"><Name>HasLocalizationKey</Name><USR>s:11cursor_info18HasLocalizationKeyV</USR><Declaration>struct HasLocalizationKey</Declaration><CommentParts><Abstract><Para>Brief.</Para></Abstract></CommentParts></Class>
784798
// CHECK87-NEXT: <LocalizationKey>ABC</LocalizationKey>
785799

@@ -793,6 +807,9 @@ let strInterpolation = "This is a \(stringStr + "ing") interpolation"
793807
// CHECK88-NEXT: cursor_info{{$}}
794808
// CHECK88-NEXT: <Declaration>func hasLocalizationKey2()</Declaration>
795809
// CHECK88-NEXT: <decl.function.free><syntaxtype.keyword>func</syntaxtype.keyword> <decl.name>hasLocalizationKey2</decl.name>()</decl.function.free>
810+
// CHECK88-NEXT: DOC COMMENT
811+
// CHECK88-NEXT: - LocalizationKey: ABC
812+
// CHECK88-NEXT: DOC COMMENT XML
796813
// CHECK88-NEXT: <Function file="{{[^"]+}}cursor_info.swift" line="216" column="6"><Name>hasLocalizationKey2()</Name><USR>s:11cursor_info19hasLocalizationKey2yyF</USR><Declaration>func hasLocalizationKey2()</Declaration><CommentParts></CommentParts></Function>
797814
// CHECK88-NEXT: <LocalizationKey>ABC</LocalizationKey>
798815

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
"\nDocComment 1\n\nDocComment 2\n"
1+
"\nDocComment 1\n\nDocComment 2"
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
"Level1\n Level2\n Level3\n Level4\n Level5\n"
1+
"Level1\n Level2\n Level3\n Level4\n Level5"
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
"Level4\nLevel3\nLevel2\nLevel1\n"
1+
"Level4\nLevel3\nLevel2\nLevel1"
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
"DocComment 1\nDocComment 2\nDocComment 3\nDocComment 4\n"
1+
"DocComment 1\nDocComment 2\nDocComment 3\nDocComment 4"

0 commit comments

Comments
 (0)