Skip to content

Commit

Permalink
[CodeCompletion] Avoid suggesting duplicated module names
Browse files Browse the repository at this point in the history
in global completion result. Overly modules have the same name as the
shadowed modules. We should not list both names because they are
identical.

Maintain a set of seen module names to avoid suggesting duplicated
names.

rdar://problem/63370253
  • Loading branch information
rintaro committed May 19, 2020
1 parent ed17e9d commit af27e8f
Show file tree
Hide file tree
Showing 6 changed files with 78 additions and 3 deletions.
12 changes: 9 additions & 3 deletions lib/IDE/CodeCompletion.cpp
Expand Up @@ -6196,6 +6196,8 @@ void CodeCompletionCallbacksImpl::doneParsing() {
break;
}

llvm::SmallPtrSet<Identifier, 8> seenModuleNames;

for (auto &Request: Lookup.RequestedCachedResults) {
// Use the current SourceFile as the DeclContext so that we can use it to
// perform qualified lookup, and to get the correct visibility for
Expand Down Expand Up @@ -6248,7 +6250,9 @@ void CodeCompletionCallbacksImpl::doneParsing() {
return; // already handled.
RequestedModules.push_back({std::move(K), TheModule,
Request.OnlyTypes, Request.OnlyPrecedenceGroups});
if (Request.IncludeModuleQualifier)

if (Request.IncludeModuleQualifier &&
seenModuleNames.insert(TheModule->getName()).second)
Lookup.addModuleName(TheModule);
}
};
Expand All @@ -6263,8 +6267,10 @@ void CodeCompletionCallbacksImpl::doneParsing() {
Lookup.getToplevelCompletions(Request.OnlyTypes);

// Add the qualifying module name
if (Request.IncludeModuleQualifier)
Lookup.addModuleName(CurDeclContext->getParentModule());
auto curModule = CurDeclContext->getParentModule();
if (Request.IncludeModuleQualifier &&
seenModuleNames.insert(curModule->getName()).second)
Lookup.addModuleName(curModule);

// Add results for all imported modules.
ModuleDecl::ImportFilter ImportFilter;
Expand Down
@@ -0,0 +1,2 @@
#include <OverlayTest/Overlayed.h>

13 changes: 13 additions & 0 deletions test/IDE/Inputs/mock-sdk/OverlayTest.framework/Headers/Overlayed.h
@@ -0,0 +1,13 @@

#ifndef OVERLAYED_H
#define OVERLAYED_H

struct __attribute__((swift_name("Overlayed"))) OVOverlayed {
double x, y, z;
};

double OVOverlayedInOriginalFunc(struct OVOverlayed s) __attribute__((swift_name("Overlayed.inOriginalFunc(self:)")));

struct OVOverlayed createOverlayed();

#endif
@@ -0,0 +1,7 @@
framework module OverlayTest {
umbrella header "OverlayTest.h"

export *
module * { export * }
}

10 changes: 10 additions & 0 deletions test/IDE/Inputs/mock-sdk/OverlayTest.swiftinterface
@@ -0,0 +1,10 @@
// swift-interface-format-version: 1.0
// swift-module-flags: -module-name OverlayTest

@_exported import OverlayTest

public extension Overlayed {
public func inOverlayFunc() {}
}

public func createOverlayedInOverlay() -> Overlayed
37 changes: 37 additions & 0 deletions test/IDE/complete_overlaymodule.swift
@@ -0,0 +1,37 @@
// RUN: %target-swift-ide-test -code-completion -source-filename %s -I %S/Inputs/mock-sdk -F %S/Inputs/mock-sdk -code-completion-token=TYPE_GLOBAL | %FileCheck %s --check-prefix=TYPE_GLOBAL
// RUN: %target-swift-ide-test -code-completion -source-filename %s -I %S/Inputs/mock-sdk -F %S/Inputs/mock-sdk -code-completion-token=EXPR_GLOBAL | %FileCheck %s --check-prefix=EXPR_GLOBAL
// RUN: %target-swift-ide-test -code-completion -source-filename %s -I %S/Inputs/mock-sdk -F %S/Inputs/mock-sdk -code-completion-token=EXPR_MEMBER | %FileCheck %s --check-prefix=EXPR_MEMBER

import OverlayTest

func testGlobalType() {
let _: #^TYPE_GLOBAL^#
// TYPE_GLOBAL: Begin completions
// TYPE_GLOBAL-NOT: OverlayTest[#Module#]
// TYPE_GLOBAL-DAG: Decl[Module]/None: OverlayTest[#Module#];
// TYPE_GLOBAL-NOT: OverlayTest[#Module#]
// TYPE_GLOBAL-DAG: Decl[Struct]/OtherModule[OverlayTest.Overlayed]: Overlayed[#Overlayed#];
// TYPE_GLOBAL: End completions
}
func testGlobalExpr() {
let _ = #^EXPR_GLOBAL^#
// EPXR_GLOBAL: Begin completions
// EXPR_GLOBAL-NOT: OverlayTest[#Module#]
// EXPR_GLOBAL-DAG: Decl[Module]/None: OverlayTest[#Module#];
// EXPR_GLOBAL-NOT: OverlayTest[#Module#]
// EXPR_GLOBAL-DAG: Decl[Struct]/OtherModule[OverlayTest.Overlayed]: Overlayed[#Overlayed#];
// EXPR_GLOBAL-DAG: Decl[FreeFunction]/OtherModule[OverlayTest]: createOverlayedInOverlay()[#Overlayed#];
// EXPR_GLOBAL-DAG: Decl[FreeFunction]/OtherModule[OverlayTest.Overlayed]: createOverlayed()[#Overlayed#];
// EPXR_GLOBAL: End completions
}
func testGlobalExpr(value: Overlayed) {
value.#^EXPR_MEMBER^#
// EXPR_MEMBER: Begin completions, 6 items
// EXPR_MEMBER-DAG: Keyword[self]/CurrNominal: self[#Overlayed#]; name=self
// EXPR_MEMBER-DAG: Decl[InstanceVar]/CurrNominal: x[#Double#]; name=x
// EXPR_MEMBER-DAG: Decl[InstanceVar]/CurrNominal: y[#Double#]; name=y
// EXPR_MEMBER-DAG: Decl[InstanceVar]/CurrNominal: z[#Double#]; name=z
// EXPR_MEMBER-DAG: Decl[InstanceMethod]/CurrNominal: inOverlayFunc()[#Void#]; name=inOverlayFunc()
// EXPR_MEMBER-DAG: Decl[InstanceMethod]/CurrNominal: inOriginalFunc()[#Double#]; name=inOriginalFunc()
// EXPR_MEMBER: End completions
}

0 comments on commit af27e8f

Please sign in to comment.