-
Notifications
You must be signed in to change notification settings - Fork 10.5k
[CodeCompletion] Give up fast-completion if dependent files are modified #31388
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
[CodeCompletion] Give up fast-completion if dependent files are modified #31388
Conversation
@swift-ci Please build toolchain macOS |
macOS Toolchain Install command |
@swift-ci Please build toolchain macOS |
e0354c9
to
09c4f2c
Compare
@swift-ci Please build toolchain macOS |
09c4f2c
to
38c26cf
Compare
@swift-ci Please build toolchain macOS |
@swift-ci Please smoke test |
9d4946e
to
95528a4
Compare
@swift-ci Please test |
Build failed |
Build failed |
95528a4
to
0f66247
Compare
@swift-ci Please test |
Build failed |
Build failed |
lib/IDE/CompletionInstance.cpp
Outdated
// If the last modification time is zero, this file is probably from a | ||
// virtual file system. We need to check the content. | ||
if (lastModTime == llvm::sys::TimePoint<>()) { | ||
if (&CI.getFileSystem() == &FS) |
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.
A couple of questions:
- Are these ever going to be equal, or in practice we'll always get a new VFS object?
- Even if the pointers are equal, is it correct to assume the contents did not change? The VFS object could be mutable.
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.
Are these ever going to be equal, or in practice we'll always get a new VFS object?
I don't think so. I believe this is unreachable.
Even if the pointers are equal, is it correct to assume the contents did not change? The VFS object could be mutable.
You are right. We perhaps should retain all buffers of the VFS dependencies. But I think it's good enough for now because the VFS objects should be always different.
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.
I would say keep a hash not the whole buffer.
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.
OK. I updated the PR to keep hashes of the dependencies.
/*HERE*/ | ||
} | ||
|
||
// FIXME: Windows CI doesn't support bash array syntax i.e. 'ARRY=( .... )' |
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.
The tests probably need
// REQUIRES: shell
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.
I didn't know shell
. Thank you!
0f66247
to
4b2ad40
Compare
@swift-ci Please test |
Build failed |
Build failed |
lib/IDE/CompletionInstance.cpp
Outdated
// If the last modification time is zero, this file is probably from a | ||
// virtual file system. We need to check the content. | ||
if (lastModTime == llvm::sys::TimePoint<>()) { | ||
if (&CI.getFileSystem() == &FS) |
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.
I would say keep a hash not the whole buffer.
lib/IDE/CompletionInstance.cpp
Outdated
|
||
// Ignore the current file and synthesized files. | ||
if (filename.empty() || filename.front() == '<' || | ||
filename.equals(currentFileName)) |
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.
Comparing filename seems potentially brittle - shouldn't we know which file is the completion buffer directly without looking at the name?
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.
Updated the PR.
4b2ad40
to
be91880
Compare
@swift-ci Please test |
Build failed |
Build failed |
lib/IDE/CompletionInstance.cpp
Outdated
// Stop processing if the modification time is not zero. Probably this | ||
// is not a virtual file system. | ||
if (stat->getLastModificationTime() != llvm::sys::TimePoint<>()) | ||
return true; |
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.
I think I'm not understanding something: why do we want to stop as soon as we see the first "normal file"? Why can't we have virtual mixed in with regular?
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.
I just want to save the stat
time if the filesystem is not in-memory.
AFAIU, in reality, we don't mix in-memory file with normal file.
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.
The filesystem you get from our builtin FileSystemProvider in sourcekitd is an overlay, so if a call is not handled by the InMemoryFilesystem, it will fall through to the RealFilesystem.
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.
Ah, thank you for notifying! Updated to just ignore the non-zero modification time here.
lib/IDE/CompletionInstance.cpp
Outdated
/// For each dependency files in CI, run \p callback until the callback returns | ||
/// \c true. Returns \c true if any callback call returns \c true, \c false | ||
/// otherwise. | ||
bool forEachDependenciesUntilTrue( |
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.
Should be singular dependency in the name: forEachDependencyUntilTrue
Check if dependencies are modified since the last checking. Dependencies: - Other source files in the current module - Dependent files collected by the dependency tracker When: - If the last dependency check was over N (defaults to 5) seconds ago Invalidate if: - The dependency file is missing - The modification time of the dependecy is greater than the last check - If the modification time is zero, compare the content using the file system from the previous completion and the current completion rdar://problem/62336432
These test cases use shell variables etc.
6210634
to
40ed3a4
Compare
// RUN: %empty-directory(%t/Frameworks) | ||
// RUN: %empty-directory(%t/MyProject) | ||
|
||
// RUN: COMPILER_ARGS=( \ |
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.
I'm not sure how supported it is to assume you can set shell variables and have them persist across run lines. This may work in practice, but are we sure lit will never run commands in a fresh environment?
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.
I'm not 100% certain this is officially supported. But several test cases rely on the behavior e.g. https://github.com/apple/swift/blob/master/test/ModuleInterface/ModuleCache/module-cache-deployment-target-irrelevant.swift.
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.
Okay, maybe we can follow up with people who know lit well, but no need to block this PR.
@swift-ci Please test |
Build failed |
Build failed |
- Detect same file with bufferID instead of the file name - Compare virtual in-memory filesystem content with hash value
40ed3a4
to
af5daed
Compare
@swift-ci Please test |
Build failed |
Build failed |
Check if dependencies are modified since the last checking.
Dependencies:
When:
Invalidate if:
rdar://problem/62336432