Skip to content

[Dependency Scanning] Have the scanner cache answer queries relevant to current search paths only. #38703

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

Merged
merged 1 commit into from
Jul 30, 2021

Conversation

artemcm
Copy link
Contributor

@artemcm artemcm commented Jul 30, 2021

The dependency scanner's cache persists across different queries and answering a subsequent query's module lookup with a module not in the query's search path is not correct.

For example, suppose we are looking for a Swift module Foo with a set of search paths SP.
And dependency scanner cache already contains a module Foo, for which we found an interface file at location L. If LSP, then we cannot re-use the cached entry because we’d be resolving the scanning query to a filesystem location that the current scanning context is not aware of.

Resolves rdar://81175942

@artemcm artemcm requested a review from nkcsgexi July 30, 2021 05:14
@artemcm
Copy link
Contributor Author

artemcm commented Jul 30, 2021

@swift-ci please test

///
/// \returns the cached result, or \c None if there is no cached entry.
Optional<ModuleDependencies> findDependencies(
StringRef moduleName,
Optional<ModuleDependenciesKind> kind,
llvm::StringSet<> &currentSearchPaths) const;
Copy link
Contributor

Choose a reason for hiding this comment

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

Nitpick: can we define a new struct, e.g. ModuleSpecifics, to contain kind and currentSearchPaths for better future extensibility?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done. 👍

return found;
}
if (auto found = cache.findDependencies(moduleName,
ModuleDependenciesKind::Clang))
ModuleDependenciesKind::Clang,
searchPathSet))
Copy link
Contributor

Choose a reason for hiding this comment

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

I'm not a big fan of duplicating the same function call for all enum cases. One technique we can use here is to define ModuleDependenciesKind::First_Kind and ModuleDependenciesKind::Last_Kind and use a for loop to iterate them. This applies to other duplications as well.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Given that this PR does not introduce this behavior, can we pursue this refactoring outside the scope of this change?

Even in this specific example there is additional complexity where simple iteration would not be enough (non-clang dependencies are skipped under a certain condition). And since this PR already re-structures quite a bit of code, I'd prefer to reduce further refactoring of existing patterns here.

Copy link
Contributor

Choose a reason for hiding this comment

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

Sure, a following PR would be much appreciated!

dependencyInfo.getModuleDependencies());

// Add the dependency-kind-specific data
if (auto swiftTextDeps = dependencyInfo.getAsSwiftTextualModule()) {
Copy link
Contributor

Choose a reason for hiding this comment

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

Instead of using chaining if-else here, can we refactor it to a switch statement?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done, thanks for pointing it out.

…to current search paths only.

The dependency scanner's cache persists across different queries and answering a subsequent query's module lookup with a module not in the query's search path is not correct.

For example, suppose we are looking for a Swift module `Foo` with a set of search paths `SP`.
And dependency scanner cache already contains a module `Foo`, for which we found an interface file at location `L`. If `L`∉`SP`, then we cannot re-use the cached entry because we’d be resolving the scanning query to a filesystem location that the current scanning context is not aware of.

Resolves rdar://81175942
@artemcm artemcm force-pushed the DepScanCacheSearchPathDisambiguate branch from 95754b2 to 6a12dc0 Compare July 30, 2021 16:53
@artemcm
Copy link
Contributor Author

artemcm commented Jul 30, 2021

@swift-ci please test

@artemcm
Copy link
Contributor Author

artemcm commented Jul 30, 2021

@swift-ci please test Windows platform

@artemcm artemcm merged commit ad7dbc5 into swiftlang:main Jul 30, 2021
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.

2 participants