Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[SourceKit] Add documentation range in structure (SR-2487) #11264

Merged
merged 3 commits into from
Aug 2, 2017

Conversation

marcelofabri
Copy link
Contributor

This PR adds the key.docoffset and key.doclength keys for declaration structures.

c78f169 removed the __raw_doc_comment attribute from structure, which was used by SwiftLint to implement some rules, for example checking if all public declarations have documentation. You can see an issue that was filled when that happened: realm/SwiftLint#728.

A while ago, @keith opened #9868 to revert that commit, but that wasn't accepted and the suggestion was to introduce new fields exposing the range of a doc comment. This is what this PR is about.

Feel free to make suggestions or point better alternative implementations.

Resolves SR-2487.

@marcelofabri
Copy link
Contributor Author

cc @nkcsgexi

@nkcsgexi nkcsgexi self-requested a review August 1, 2017 17:22
@@ -772,6 +774,7 @@ bool ModelASTWalker::walkToDeclPre(Decl *D) {
AFD->getBodySourceRange());
SN.NameRange = charSourceRangeFromSourceRange(SM,
AFD->getSignatureSourceRange());
SN.DocRange = findDocCommentRange(AFD->getAttrs());
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can we have a function called setDecl(SyntaxStructureNode&,Decl*); where it sets both the decl pointer SN.Dcl and SN.DocRange? so all these added lines can call this function.

}
else {
DocOffset = DocEnd = 0;
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Initialize DocOffset and DocEnd with 0 so we don't need the else block.

}
}
return CharSourceRange();
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We really don't need a member function here. A static function in the file will be sufficient.

@marcelofabri
Copy link
Contributor Author

@nkcsgexi I've rebased and addressed your feedback 💯

@@ -418,6 +418,21 @@ CharSourceRange parameterNameRangeOfCallArg(const TupleExpr *TE,
return CharSourceRange();
}

CharSourceRange findDocCommentRange(DeclAttributes Attrs) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can we declare this function as static explicitly?

return CharSourceRange();
}

void setDecl(SyntaxStructureNode &N, Decl *D) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same here, declared as static void setDecl()

@nkcsgexi
Copy link
Contributor

nkcsgexi commented Aug 1, 2017

@swift-ci please smoke test and merge

@nkcsgexi
Copy link
Contributor

nkcsgexi commented Aug 1, 2017

@swift-ci please smoke test and merge

This PR adds the “key.docoffset” and “key.doclength” keys for declaration structures.
@marcelofabri
Copy link
Contributor Author

I've rebased and (hopefully) addressed the CI failure.

@CodaFi
Copy link
Contributor

CodaFi commented Aug 2, 2017

@swift-ci please smoke test

static CharSourceRange findDocCommentRange(DeclAttributes Attrs) {
for (auto Attr : Attrs) {
if (auto DocAttr = dyn_cast_or_null<RawDocCommentAttr>(Attr)) {
return DocAttr->getCommentRange();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

RawDocCommentAttr::getCommentRange returns raw comment range. For example:

// Copyright (c) FooBar Inc.

/// secret.
func doSomething() {

IIRC, getCommentRange() returns from // Copy on line 1 to secret.\n on line 3.
Is that desired behavior?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is that desired behavior?

Not really 😅

I've tested it and it indeed returns everything. Do you have any suggestions on how to improve this?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Well, interface printing uses Decl::getRawComment for extracting doc comments, but I'm not sure we can use that here. It might be too costly for this purpose.
@nkcsgexi ?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good catch! @rintaro I cannot think of any reason not using Decl::getRawComment here, If we care only attached doc comment in the use case.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

how do I get a range from a RawComment? 🤔

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could we add a function getCharSourceRange() to RawComment that analyses the enclosed SingleRawComment where range is available?

Copy link
Member

@rintaro rintaro Aug 2, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Something like this I guess:

RawComment Raw = ...
if (!Raw.isEmpty()) {
  auto Start = Raw.Comments.front().Range.getStart();
  auto End = Raw.Comments.back().Range.getEnd();

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Updated!

Copy link
Contributor

@nkcsgexi nkcsgexi left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good job on addressing comments! some more inline : )


auto Start = this->Comments.front().Range.getStart();
auto End = this->Comments.back().Range.getEnd();
return CharSourceRange(SM, Start, End);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We actually don't need SM here, it's reasonable to assume Start and End are well formed. so something like:

  return CharSourceRange(Start, (char*)End.getOpaquePointerValue() -
    (char*)Start.getOpaquePointerValue());

return CharSourceRange();
}

auto Start = this->Comments.front().Range.getStart();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could we have an early return if Start is invalid? cause the doc comment may come from a deserialized module file.

@@ -418,6 +418,12 @@ CharSourceRange parameterNameRangeOfCallArg(const TupleExpr *TE,
return CharSourceRange();
}

static void setDecl(SyntaxStructureNode &N, Decl *D, const SourceManager &SM) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

so, we don't need SM here either.

@nkcsgexi
Copy link
Contributor

nkcsgexi commented Aug 2, 2017

@swift-ci please smoke test

@nkcsgexi nkcsgexi merged commit d16cce3 into swiftlang:master Aug 2, 2017
@marcelofabri marcelofabri deleted the doc-range-sourcekit branch August 2, 2017 20:53
rintaro added a commit to rintaro/swift that referenced this pull request Feb 20, 2018
llvm::SourceMgr caches the line and column of the last query. It
usually scans from that position for subsequent queries. However, if the
query is for a position ahead of the last query, it re-scan from the top
of the whole buffer. This significally slows down the performance.

This change effectively mitigate performance regression introduced in
swiftlang#11264 without functional changes.
rintaro added a commit to rintaro/swift that referenced this pull request Feb 20, 2018
llvm::SourceMgr caches the line and column of the last query. It
usually scans from that position for subsequent queries. However, if the
query is for a position ahead of the last query, it re-scan from the top
of the whole buffer. This significally slows down the performance.

This change effectively mitigate performance regression introduced in
swiftlang#11264 without functional changes.
rintaro added a commit to rintaro/swift that referenced this pull request Feb 20, 2018
llvm::SourceMgr caches the line and column of the last query. It
usually scans from that position for subsequent queries. However, if the
query is for a position ahead of the last query, it re-scan from the top
of the whole buffer. This significally slows down the performance.

This change effectively mitigate performance regression introduced in
swiftlang#11264 without functional changes.
rintaro added a commit that referenced this pull request Feb 21, 2018
…ent (#14733)

llvm::SourceMgr caches the line and column of the last query. It
usually scans from that position for subsequent queries. However, if the
query is for a position ahead of the last query, it re-scan from the top
of the whole buffer. This significally slows down the performance.

This change effectively mitigate performance regression introduced in
#11264 without functional changes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants