Skip to content

[CodeCompletion] Complete Swift only module name after 'import' #24455

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 6 commits into from
May 8, 2019

Conversation

rintaro
Copy link
Member

@rintaro rintaro commented May 3, 2019

For each ModuleLoader, newly implement collectVisibleTopLevelModuleNames() which collects visible module names. It doesn't care about the actual content of the file though. So it doesn't guarantee the module is loadable.

rdar://problem/39392446

@rintaro rintaro force-pushed the ide-complete-import-swiftmodule branch 4 times, most recently from e3bfbc0 to 3f3ff69 Compare May 3, 2019 22:03
@rintaro
Copy link
Member Author

rintaro commented May 3, 2019

@swift-ci Please smoke test

@rintaro rintaro marked this pull request as ready for review May 3, 2019 22:04
@rintaro rintaro requested review from benlangmuir and jrose-apple May 3, 2019 22:04
if (ModuleName.str().startswith("_"))
continue;
if (ModuleName == Ctx.SwiftShimsModuleName)
continue;
Copy link
Member Author

Choose a reason for hiding this comment

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

Are there other module names we should hide? e.g. SwiftOnoneSupport

Copy link
Contributor

Choose a reason for hiding this comment

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

Yeah, that one seems worth hiding. That's probably all we want to hardcode in the tools.

Copy link
Contributor

Choose a reason for hiding this comment

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

+1 to skipping OnoneSupport (looks like the name is in Strings.h). Other modules we should skip: __C, __C_Synthesized, Builtin. I'm guessing they are already hidden because they're not on the file system, but please add CHECK-NOTs for them.

Copy link
Contributor

Choose a reason for hiding this comment

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

_InternalSwiftSyntaxParser is another one we don't want to show. Should already be covered, but again, worth a test to make sure.

}
case SearchPathKind::Framework: {
// Look for:
// $PATH/{name}.framework/Modules/{name}.swiftmodule/{arch}.{extension}
Copy link
Member Author

Choose a reason for hiding this comment

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

Not sure we need to handle frameworks practically. If framework always have Clang module (module.modulemap) with corresponding module name, ClangImporter can find them.
@jrose-apple Is pure Swift only framework possible?

Copy link
Contributor

Choose a reason for hiding this comment

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

Yes, unfortunately.

@rintaro rintaro force-pushed the ide-complete-import-swiftmodule branch 2 times, most recently from fb5c6f3 to 3b099bb Compare May 4, 2019 00:02
@rintaro
Copy link
Member Author

rintaro commented May 4, 2019

@swift-ci Please test

@swift-ci
Copy link
Contributor

swift-ci commented May 4, 2019

Build failed
Swift Test OS X Platform
Git Sha - 3f3ff69e79c2b4ce3539eb4f21b6e72e13e4381a

@swift-ci
Copy link
Contributor

swift-ci commented May 4, 2019

Build failed
Swift Test Linux Platform
Git Sha - 3f3ff69e79c2b4ce3539eb4f21b6e72e13e4381a

@rintaro
Copy link
Member Author

rintaro commented May 6, 2019

@swift-ci Please test

@swift-ci
Copy link
Contributor

swift-ci commented May 6, 2019

Build failed
Swift Test Linux Platform
Git Sha - 3b099bbc8d766f8d41eb800931737ba24c1d64ba

@swift-ci
Copy link
Contributor

swift-ci commented May 6, 2019

Build failed
Swift Test OS X Platform
Git Sha - 3b099bbc8d766f8d41eb800931737ba24c1d64ba

auto MD = ModuleDecl::create(Ctx.getIdentifier(ModuleName), Ctx);
if (ModuleName == mainModuleName)
continue;
if (ModuleName.str().startswith("_"))
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 happy about this case, but since it's just been copied okay...

if (ModuleName.str().startswith("_"))
continue;
if (ModuleName == Ctx.SwiftShimsModuleName)
continue;
Copy link
Contributor

Choose a reason for hiding this comment

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

+1 to skipping OnoneSupport (looks like the name is in Strings.h). Other modules we should skip: __C, __C_Synthesized, Builtin. I'm guessing they are already hidden because they're not on the file system, but please add CHECK-NOTs for them.


// Check whether target specific module file exists or not in given directory.
// $PATH/{arch}.{extension}
auto checkTargetFiles = [&](StringRef path) -> bool {
Copy link
Contributor

Choose a reason for hiding this comment

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

Is there any point in checking these instead of just detecting the presence of the .swiftmodule directory/file? We aren't checking if the module is importable.

Copy link
Contributor

Choose a reason for hiding this comment

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

That'd be faster but might mean less common code between both code paths.

Copy link
Contributor

Choose a reason for hiding this comment

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

Good point. I'm okay with this if it's not a big perf issue and keeps the code simpler.

Copy link
Contributor

@jrose-apple jrose-apple left a comment

Choose a reason for hiding this comment

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

I haven't taken a close look at the refactoring for SerializedModuleLoaderBase yet, but here's some initial comments. (Seems intricate…)

if (ModuleName.str().startswith("_"))
continue;
if (ModuleName == Ctx.SwiftShimsModuleName)
continue;
Copy link
Contributor

Choose a reason for hiding this comment

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

Yeah, that one seems worth hiding. That's probably all we want to hardcode in the tools.

@@ -70,6 +70,11 @@ class SkipNonTransparentFunctions : public DelayedParsingCallbacks {

} // unnamed namespace

void SourceLoader::collectVisibleTopLevelModuleNames(
SmallVectorImpl<Identifier> &names) const {
// TODO: Implement?
Copy link
Contributor

Choose a reason for hiding this comment

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

Nah, SourceLoader's going away soon. (As soon as I can convert the tests over to using module interfaces.)


/// Apply \c body for each target-specific module file base name to search.
void forEachTargetModuleBasename(const ASTContext &Ctx,
llvm::function_ref<void(StringRef)> body) {
Copy link
Contributor

Choose a reason for hiding this comment

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

Nitpick: LLVM style is to double-indent the wrapped line (and then single-indent the following lines), and I think we consistently wrap all parameters if any of them can't be aligned to the open paren.

Copy link
Member Author

Choose a reason for hiding this comment

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

Ah, I forgot to apply clang-format to this block. Thanks!

}
case SearchPathKind::Framework: {
// Look for:
// $PATH/{name}.framework/Modules/{name}.swiftmodule/{arch}.{extension}
Copy link
Contributor

Choose a reason for hiding this comment

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

Yes, unfortunately.

@jrose-apple jrose-apple requested a review from beccadax May 6, 2019 17:22
@beccadax
Copy link
Contributor

beccadax commented May 6, 2019

Initial reaction is that I like the module loading refactoring quite a bit, but I'll need to study it more to see if it preserves behavior.

@rintaro rintaro force-pushed the ide-complete-import-swiftmodule branch from cce47c6 to 9b83c3e Compare May 6, 2019 18:41
Copy link
Contributor

@beccadax beccadax left a comment

Choose a reason for hiding this comment

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

The SerializedModuleLoaderBase refactoring is so nice. I knew there was a small, sensible function struggling to escape from that mess.

return result;

// Apple platforms have extra implicit framework search paths:
// $SDKROOT/System/Library/Frameworks/ ; and
Copy link
Contributor

Choose a reason for hiding this comment

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

This comment seems to have picked up a semicolon in the move.

// Apply \p body for each directory entry in \p dirPath.
auto forEachDirectoryEntryPath =
[&](StringRef dirPath, llvm::function_ref<void(StringRef)> body) {
std::error_code errorCode;
Copy link
Contributor

Choose a reason for hiding this comment

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

I suppose you're intentionally ignoring the error code here?

Copy link
Member Author

Choose a reason for hiding this comment

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

errorCode is handled in for condition. for (; !errorCode && DI != End;...

// Look for:
// (Darwin OS) $PATH/{name}.swiftmodule/{arch}.{extension}
// (Other OS) $PATH/{name}.{extension}
bool requireTargetSpecificModule = Ctx.LangOpts.Target.isOSDarwin();
Copy link
Contributor

Choose a reason for hiding this comment

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

This isOSDarwin() test for RuntimeLibrary is written twice. Could we centralize it somehow? Maybe by splitting RuntimeLibrary into TargetSpecificRuntimeLibrary and TargetIndependentRuntimeLibrary?

Alternatively, maybe forEachModuleSearchPath() could pass additional parameters with flags for "can be target independent" and "can be target dependent" (or a single tri-state value). That might allow you to unify more of the framework and non-framework paths in these functions.

Copy link
Member Author

Choose a reason for hiding this comment

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

That seems to be a good idea. Let me try it in follow-ups.

@@ -228,6 +401,7 @@ SerializedModuleLoaderBase::findModule(AccessPathElem moduleID,

// We can only get here if all targetFileNamePairs failed with
// 'std::errc::no_such_file_or_directory'.
auto normalizedTarget = getTargetSpecificModuleTriple(Ctx.LangOpts.Target);
Copy link
Contributor

Choose a reason for hiding this comment

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

We're going to recompute this pretty often if it's inside the lambda, but I guess it'll be swamped by I/O anyway.

Copy link
Member Author

Choose a reason for hiding this comment

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

This is diagnostics code path. I don't expect this code is going to be executed so often. Am I missing something?

Copy link
Contributor

Choose a reason for hiding this comment

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

If we end up at the return None; after this, we may still successfully load a module from a later search path. But I guess that only happens if there's a .swiftmodule directory and the directory doesn't contain any accessible .swiftmodule files, so it's not likely to happen repeatedly.

(Hmm, I don't think failed #if canImport(...) results are cached anywhere...unrelated, just something I noticed.)

Copy link
Member Author

Choose a reason for hiding this comment

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

Ah, that's true. Thank you for explanation!

Copy link
Member Author

Choose a reason for hiding this comment

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

Decided to use the first name from forEachTargetModuleBasename()

if (ModuleName.str().startswith("_"))
continue;
if (ModuleName == Ctx.SwiftShimsModuleName)
continue;
Copy link
Contributor

Choose a reason for hiding this comment

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

_InternalSwiftSyntaxParser is another one we don't want to show. Should already be covered, but again, worth a test to make sure.

@rintaro rintaro force-pushed the ide-complete-import-swiftmodule branch from 1d317fd to 334685b Compare May 6, 2019 22:35
@rintaro
Copy link
Member Author

rintaro commented May 6, 2019

@swift-ci Please smoke test

1 similar comment
@rintaro
Copy link
Member Author

rintaro commented May 6, 2019

@swift-ci Please smoke test

@rintaro rintaro force-pushed the ide-complete-import-swiftmodule branch from 3fd99cf to 334685b Compare May 7, 2019 23:35
rintaro added 2 commits May 8, 2019 10:11
- forEachTargetModuleBasename(): Iterate through target names to search
- forEachModuleSearchPath(): Iterate through search paths
@rintaro rintaro force-pushed the ide-complete-import-swiftmodule branch from 334685b to d02f170 Compare May 8, 2019 17:23
@rintaro
Copy link
Member Author

rintaro commented May 8, 2019

@swift-ci Please smoke test

Maintain an invariant that forEachTargetModuleBasename() iterates names
from most to least desiable.
@rintaro rintaro force-pushed the ide-complete-import-swiftmodule branch from d02f170 to 0d43e5a Compare May 8, 2019 19:42
@rintaro
Copy link
Member Author

rintaro commented May 8, 2019

@swift-ci Please smoke test

@jrose-apple
Copy link
Contributor

*sigh* I think the tri-state Optional<bool> ended up causing rdar://problem/50789839. I'll probably go through and replace it all with an enum.

@rintaro
Copy link
Member Author

rintaro commented Jun 20, 2019

@jrose-apple Could you elaborate? Did I make a mistake?

@jrose-apple
Copy link
Contributor

I'm not sure. This morning I'm thinking about it more and I think you didn't make a mistake, but I'm still taking this as evidence that the code isn't as easy-to-read as it could be.

@jrose-apple
Copy link
Contributor

(The issue is that ParseableInterfaceModuleLoader is failing but the compilation process overall is "succeeding", i.e. exiting with an exit code of 0.)

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.

5 participants