-
Notifications
You must be signed in to change notification settings - Fork 10.5k
[AST] Formalize getBodySourceRange() for fast completion #33421
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
[AST] Formalize getBodySourceRange() for fast completion #33421
Conversation
Fast completion replaces the body ('BraceStmt') of function decls with other bodies parsed from different source buffers from the original source buffer. That means the source range of the body and the location of the function declaration itself might be in different buffers. Previously, FuncDecl::getSourceRange() used to use the 'func' keyword decl as the start loc and 'getBodySourceRange().End' as the end loc. This breaks a SourceRange invariant where the start and end loc must be in the same buffer. This patch add a new function 'getOriginalBodySourceRange()' which always return the source range of the original body of the function. And use that from 'getSourceRange()' functions. The orignal body source range is stored in a side table in ASTContext so that normal compilation doesn't consume space for that extra info.
@swift-ci Please smoke test |
lib/AST/Decl.cpp
Outdated
void AbstractFunctionDecl::setBodyToBeReparsed(SourceRange bodyRange) { | ||
assert(bodyRange.isValid()); | ||
assert(getBodyKind() == BodyKind::None || | ||
getBodyKind() == BodyKind::Skipped || |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
To make sure I understand this invariant: why is code-completion expecting None
and Skipped
rather than Unparsed
? Before we started reusing the ASTContext, I understand that "skipped" would make sense, but now that we may go back and parse it later, why is it not Unparsed
? And how can None
happen? Does that means the user changed func foo()
to func foo() {}
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good point.
None
is not necessary here. func foo()
-> func foo() { #^A^# }
changes the interface hash and is not supported in fast-completion. Will remove it.
Also, non-target functions are marked as Skipped
without a reason. I'm going to stop marking them Skipped
and change this assertion to
assert(getBodyKind() == BodyKind::Unparsed ||
getBodyKind() == BodyKind::Parsed ||
getBodyKind() == BodyKind::TypeChecked);
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
438fff7
to
ee6c6f4
Compare
@swift-ci Please smoke test |
Windows failures are unrelated. |
Fast code-completion replaces the body (
BraceStmt
) of function decls with other bodies parsed from different source buffers. That means the source range of the body and the location of the function declaration itself might be in different buffers. Previously,FuncDecl::getSourceRange()
used to use the location offunc
keyword forgetStartLoc()
andgetBodySourceRange().End
forgetEndLoc()
. This breaks an invariant forSourceRange
where the start and end loc must be in the same buffer.This patch adds a new function
getOriginalBodySourceRange()
which always return the source range of the original body of the function. And use that fromgetSourceRange()
functions. The original body source range is stored in a side table inASTContext
.This formalize the semantics of
AbstractFunctionDecl::getBodySouceRange()
that it always returns the source range of the current body.No observable functional changes are expected.