Skip to content

Commit 5cfb9b9

Browse files
committed
Merge branch 'eugene-auduchinok-import_path_from_test'
2 parents 345a687 + 58aee87 commit 5cfb9b9

File tree

11 files changed

+180
-39
lines changed

11 files changed

+180
-39
lines changed

src/com/goide/codeInsight/imports/GoImportPackageQuickFix.java

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
import com.goide.psi.GoFile;
2323
import com.goide.psi.GoReferenceExpression;
2424
import com.goide.psi.GoTypeReferenceExpression;
25+
import com.goide.runconfig.testing.GoTestFinder;
2526
import com.goide.stubs.index.GoPackagesIndex;
2627
import com.goide.util.GoUtil;
2728
import com.intellij.codeInsight.hint.HintManager;
@@ -160,18 +161,25 @@ private Collection<String> getPackagesToImport(@NotNull PsiElement element) {
160161
if (myPackagesToImport == null) {
161162
final GlobalSearchScope scope = GoUtil.moduleScope(element);
162163
PsiFile file = element.getContainingFile();
163-
final PsiDirectory parentDirectory = file != null ? file.getParent() : null;
164164
Project project = element.getProject();
165+
final PsiDirectory parentDirectory = file != null ? file.getParent() : null;
165166
final GoExcludedPathsSettings excludedSettings = GoExcludedPathsSettings.getInstance(project);
167+
final String testTargetPackage = GoTestFinder.getTestTargetPackage(file);
166168
Collection<GoFile> es = StubIndex.getElements(GoPackagesIndex.KEY, myPackageName, project, scope, GoFile.class);
167169
myPackagesToImport = sorted(skipNulls(map2Set(
168170
es,
169171
new Function<GoFile, String>() {
170172
@Nullable
171173
@Override
172174
public String fun(@NotNull GoFile file) {
173-
String importPath = parentDirectory == null || !parentDirectory.isEquivalentTo(file.getParent()) ? file.getImportPath() : null;
174-
return importPath != null && !excludedSettings.isExcluded(importPath) ? importPath : null;
175+
if (parentDirectory != null && parentDirectory.isEquivalentTo(file.getParent())) {
176+
if (testTargetPackage == null || !testTargetPackage.equals(file.getPackageName())) {
177+
return null;
178+
}
179+
}
180+
181+
String importPath = file.getImportPath();
182+
return !excludedSettings.isExcluded(importPath) ? importPath : null;
175183
}
176184
}
177185
)), new MyImportsComparator(element));

src/com/goide/completion/GoAutoImportCompletionContributor.java

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
import com.goide.psi.*;
2121
import com.goide.psi.impl.GoPsiImplUtil;
2222
import com.goide.psi.impl.GoTypeReference;
23+
import com.goide.runconfig.testing.GoTestFinder;
2324
import com.goide.util.GoUtil;
2425
import com.intellij.codeInsight.completion.*;
2526
import com.intellij.openapi.progress.ProgressManager;
@@ -58,10 +59,10 @@ protected void addCompletions(@NotNull CompletionParameters parameters,
5859
PsiElement position = parameters.getPosition();
5960
PsiElement parent = position.getParent();
6061
if (prevDot(parent)) return;
61-
PsiFile file = parameters.getOriginalFile();
62-
if (!(file instanceof GoFile)) return;
63-
if (!(parent instanceof GoReferenceExpressionBase)) return;
64-
62+
PsiFile psiFile = parameters.getOriginalFile();
63+
if (!(psiFile instanceof GoFile && parent instanceof GoReferenceExpressionBase)) return;
64+
GoFile file = (GoFile)psiFile;
65+
6566
result = adjustMatcher(parameters, result, parent);
6667
PrefixMatcher matcher = result.getPrefixMatcher();
6768
if (parameters.getInvocationCount() < 2 && matcher.getPrefix().isEmpty()) {
@@ -82,14 +83,14 @@ protected void addCompletions(@NotNull CompletionParameters parameters,
8283
}
8384
if (processors.isEmpty()) return;
8485

85-
NamedElementProcessor processor = new NamedElementProcessor(processors, ((GoFile)file).getImportedPackagesMap(), result);
86+
NamedElementProcessor processor = new NamedElementProcessor(processors, file.getImportedPackagesMap(), result);
8687
Project project = position.getProject();
8788
GlobalSearchScope scope = GoUtil.moduleScopeWithoutTests(file);
8889
VirtualFile containingDirectory = file.getVirtualFile().getParent();
8990
if (containingDirectory != null) {
90-
scope = new GoUtil.ExceptChildOfDirectory(containingDirectory, scope);
91+
scope = new GoUtil.ExceptChildOfDirectory(containingDirectory, scope, GoTestFinder.getTestTargetPackage(file));
9192
}
92-
Set<String> sortedKeys = sortMatching(matcher, StubIndex.getInstance().getAllKeys(ALL_PUBLIC_NAMES, project), ((GoFile)file));
93+
Set<String> sortedKeys = sortMatching(matcher, StubIndex.getInstance().getAllKeys(ALL_PUBLIC_NAMES, project), file);
9394
for (String name : sortedKeys) {
9495
processor.setName(name);
9596
StubIndex.getInstance().processElements(ALL_PUBLIC_NAMES, name, project, scope, GoNamedElement.class, processor);
@@ -106,7 +107,7 @@ private CompletionResultSet adjustMatcher(@NotNull CompletionParameters paramete
106107
});
107108
}
108109

109-
private static Set<String> sortMatching(@NotNull PrefixMatcher matcher, @NotNull Collection<String> names, @NotNull GoFile file) {
110+
private static Set<String> sortMatching(@NotNull PrefixMatcher matcher, @NotNull Collection<String> names, @NotNull GoFile file) {
110111
ProgressManager.checkCanceled();
111112
String prefix = matcher.getPrefix();
112113
if (prefix.isEmpty()) return ContainerUtil.newLinkedHashSet(names);
@@ -313,11 +314,11 @@ private static Boolean cachedAllowed(@NotNull GoNamedElement element, @Nullable
313314

314315
private ExistingImportData cachedImportData(@NotNull GoNamedElement element, @Nullable ExistingImportData existingValue) {
315316
if (existingValue != null) return existingValue;
316-
317+
317318
GoFile declarationFile = element.getContainingFile();
318319
String importPath = declarationFile.getImportPath();
319320
GoImportSpec existingImport = myImportedPackages.get(importPath);
320-
321+
321322
boolean exists = existingImport != null;
322323
boolean isDot = exists && existingImport.isDot();
323324
String alias = existingImport != null ? existingImport.getAlias() : null;

src/com/goide/completion/GoImportPathsCompletionProvider.java

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
import com.goide.GoFileType;
2020
import com.goide.project.GoExcludedPathsSettings;
2121
import com.goide.psi.GoImportString;
22+
import com.goide.runconfig.testing.GoTestFinder;
2223
import com.goide.sdk.GoSdkUtil;
2324
import com.goide.util.GoUtil;
2425
import com.intellij.codeInsight.completion.CompletionParameters;
@@ -31,6 +32,7 @@
3132
import com.intellij.openapi.util.text.StringUtil;
3233
import com.intellij.openapi.vfs.VirtualFile;
3334
import com.intellij.psi.PsiElement;
35+
import com.intellij.psi.PsiFile;
3436
import com.intellij.psi.search.FileTypeIndex;
3537
import com.intellij.psi.search.GlobalSearchScope;
3638
import com.intellij.psi.util.PsiTreeUtil;
@@ -62,11 +64,14 @@ public static void addCompletions(@NotNull CompletionResultSet result,
6264
String contextImportPath = GoCompletionUtil.getContextImportPath(context);
6365
GoExcludedPathsSettings excludedSettings = GoExcludedPathsSettings.getInstance(project);
6466
GlobalSearchScope scope = withLibraries ? GoUtil.moduleScope(module) : GoUtil.moduleScopeWithoutLibraries(module);
67+
PsiFile contextFile = context != null ? context.getContainingFile() : null;
68+
boolean testFileWithTestPackage = GoTestFinder.isTestFileWithTestPackage(contextFile);
6569
for (VirtualFile file : FileTypeIndex.getFiles(GoFileType.INSTANCE, scope)) {
6670
VirtualFile parent = file.getParent();
6771
if (parent == null) continue;
6872
String importPath = GoSdkUtil.getPathRelativeToSdkAndLibraries(parent, project, module);
69-
if (!StringUtil.isEmpty(importPath) && !importPath.equals(contextImportPath) && !excludedSettings.isExcluded(importPath)) {
73+
if (!StringUtil.isEmpty(importPath) && !excludedSettings.isExcluded(importPath) &&
74+
(testFileWithTestPackage || !importPath.equals(contextImportPath))) {
7075
result.addElement(GoCompletionUtil.createPackageLookupElement(importPath, contextImportPath, false));
7176
}
7277
}

src/com/goide/project/GoExcludedPathsSettings.java

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,10 @@ public void setExcludedPackages(String... excludedPackages) {
5959
incModificationCount();
6060
}
6161

62-
public boolean isExcluded(@NotNull String importPath) {
62+
public boolean isExcluded(@Nullable String importPath) {
63+
if (importPath == null) {
64+
return false;
65+
}
6366
for (String excludedPath : myExcludedPackages) {
6467
if (FileUtil.isAncestor(excludedPath, importPath, false)) return true;
6568
}

src/com/goide/psi/GoFile.java

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -492,5 +492,4 @@ public boolean value(PsiComment comment) {
492492
}
493493
});
494494
}
495-
496495
}

src/com/goide/runconfig/testing/GoTestFinder.java

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ public class GoTestFinder implements TestFinder {
3939
private static final String EXTENSION = "." + GoFileType.INSTANCE.getDefaultExtension();
4040

4141
public static boolean isTestFile(@Nullable PsiFile file) {
42-
return file != null && file instanceof GoFile && file.getName().endsWith(GoConstants.TEST_SUFFIX_WITH_EXTENSION);
42+
return file instanceof GoFile && file.getName().endsWith(GoConstants.TEST_SUFFIX_WITH_EXTENSION);
4343
}
4444

4545
public static boolean isTestFile(@Nullable VirtualFile file) {
@@ -51,6 +51,21 @@ public static String getTestFunctionName(@NotNull GoFunctionOrMethodDeclaration
5151
return GoTestFunctionType.fromName(function.getName()) == GoTestFunctionType.TEST ? StringUtil.notNullize(function.getName()) : null;
5252
}
5353

54+
public static boolean isTestFileWithTestPackage(@Nullable PsiFile file) {
55+
return getTestTargetPackage(file) != null;
56+
}
57+
58+
@Nullable
59+
public static String getTestTargetPackage(@Nullable PsiFile file) {
60+
if (isTestFile(file)) {
61+
String packageName = ((GoFile)file).getPackageName();
62+
if (packageName != null && packageName.endsWith(GoConstants.TEST_SUFFIX)) {
63+
return StringUtil.nullize(StringUtil.trimEnd(packageName, GoConstants.TEST_SUFFIX));
64+
}
65+
}
66+
return null;
67+
}
68+
5469
@Nullable
5570
@Override
5671
public PsiElement findSourceElement(@NotNull PsiElement from) {

src/com/goide/util/GoUtil.java

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@
3434
import com.intellij.psi.PsiDirectory;
3535
import com.intellij.psi.PsiElement;
3636
import com.intellij.psi.PsiFile;
37+
import com.intellij.psi.PsiManager;
3738
import com.intellij.psi.search.DelegatingGlobalSearchScope;
3839
import com.intellij.psi.search.GlobalSearchScope;
3940
import com.intellij.psi.util.CachedValue;
@@ -245,15 +246,32 @@ public boolean contains(@NotNull VirtualFile file) {
245246

246247
public static class ExceptChildOfDirectory extends DelegatingGlobalSearchScope {
247248
@NotNull private final VirtualFile myParent;
249+
@Nullable private final String myAllowedPackageInExcludedDirectory;
248250

249-
public ExceptChildOfDirectory(@NotNull VirtualFile parent, @NotNull GlobalSearchScope baseScope) {
251+
public ExceptChildOfDirectory(@NotNull VirtualFile parent,
252+
@NotNull GlobalSearchScope baseScope,
253+
@Nullable String allowedPackageInExcludedDirectory) {
250254
super(baseScope);
251255
myParent = parent;
256+
myAllowedPackageInExcludedDirectory = allowedPackageInExcludedDirectory;
252257
}
253258

254259
@Override
255260
public boolean contains(@NotNull VirtualFile file) {
256-
return !myParent.equals(file.getParent()) && super.contains(file);
261+
if (myParent.equals(file.getParent())) {
262+
if (myAllowedPackageInExcludedDirectory == null) {
263+
return false;
264+
}
265+
Project project = getProject();
266+
PsiFile psiFile = project != null ? PsiManager.getInstance(project).findFile(file) : null;
267+
if (!(psiFile instanceof GoFile)) {
268+
return false;
269+
}
270+
if (!myAllowedPackageInExcludedDirectory.equals(((GoFile)psiFile).getPackageName())) {
271+
return false;
272+
}
273+
}
274+
return super.contains(file);
257275
}
258276
}
259277

tests/com/goide/codeInsight/imports/GoReferenceImporterTest.java

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,12 +20,18 @@
2020
import com.goide.inspections.unresolved.GoUnresolvedReferenceInspection;
2121
import com.intellij.codeInsight.CodeInsightSettings;
2222
import com.intellij.codeInsight.daemon.DaemonCodeAnalyzerSettings;
23+
import com.intellij.codeInsight.intention.IntentionAction;
2324
import com.intellij.openapi.command.undo.UndoManager;
2425
import com.intellij.openapi.fileEditor.FileEditor;
2526
import com.intellij.openapi.fileEditor.FileEditorManager;
27+
import com.intellij.openapi.vfs.VirtualFile;
2628
import com.intellij.testFramework.LightProjectDescriptor;
29+
import com.intellij.testFramework.fixtures.TempDirTestFixture;
2730
import com.intellij.testFramework.fixtures.impl.CodeInsightTestFixtureImpl;
2831

32+
import java.io.IOException;
33+
import java.util.List;
34+
2935

3036
public class GoReferenceImporterTest extends GoCodeInsightFixtureTestCase {
3137
private boolean defaultJavaOnTheFly;
@@ -104,4 +110,34 @@ public void testOnTheFlyEnabledJavaOnTheFlyDisabled() {
104110
public void testOnTheFlyDisabledJavaOnTheFlyDisabled() {
105111
doTestAddOnTheFly(false, false);
106112
}
113+
114+
private void doTestImportOwnPath(String file, String text, String testFile, String testText, String path, boolean shouldImport)
115+
throws IOException {
116+
DaemonCodeAnalyzerSettings.getInstance().setImportHintEnabled(true);
117+
updateSettings(true, true);
118+
119+
TempDirTestFixture dir = myFixture.getTempDirFixture();
120+
dir.createFile(path + "/" + file, text);
121+
VirtualFile test = dir.createFile(path + "/" + testFile, testText);
122+
myFixture.configureFromExistingVirtualFile(test);
123+
List<IntentionAction> actions = myFixture.filterAvailableIntentions("Import " + path + "?");
124+
assertTrue(shouldImport != actions.isEmpty());
125+
}
126+
127+
public void testOwnAddPathFromTest() throws IOException {
128+
doTestImportOwnPath("a.go", "package myPack; func Func() {}",
129+
"a_test.go", "package myPack_test; func TestFunc() { my<caret>Pack.Func() }",
130+
"pack", true);
131+
}
132+
133+
public void testDoNotImportOwnPathFromDifferentPackage() throws IOException {
134+
doTestImportOwnPath("a.go", "package pack1; func Func() {}",
135+
"a_test.go", "package pack2_test; func TestFunc() { pack<caret>1.Func() }",
136+
"pack", false);
137+
}
138+
139+
public void testCompleteDifferentPackageFromTest() {
140+
myFixture.configureByText("a.go", "package foo; func a() { fmt.Print<caret> }");
141+
assertNotEmpty(myFixture.getLookupElementStrings());
142+
}
107143
}

tests/com/goide/completion/GoCompletionSdkAwareTest.java

Lines changed: 43 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -19,22 +19,12 @@
1919
import com.intellij.codeInsight.completion.CompletionType;
2020
import com.intellij.codeInsight.lookup.Lookup;
2121
import com.intellij.openapi.vfs.VirtualFile;
22-
import com.intellij.testFramework.LightProjectDescriptor;
22+
import com.intellij.testFramework.fixtures.TempDirTestFixture;
2323

2424
import java.io.IOException;
25+
import java.util.List;
2526

26-
public class GoCompletionSdkAwareTest extends GoCompletionTestBase {
27-
@Override
28-
public void setUp() throws Exception {
29-
super.setUp();
30-
setUpProjectSdk();
31-
}
32-
33-
@Override
34-
protected LightProjectDescriptor getProjectDescriptor() {
35-
return createMockProjectDescriptor();
36-
}
37-
27+
public class GoCompletionSdkAwareTest extends GoCompletionSdkAwareTestBase {
3828
public void testFormatter() {
3929
doTestInclude("package main; import . \"fmt\"; type alias <caret>", "Formatter");
4030
}
@@ -79,15 +69,15 @@ public void testFunctionAutoImport() {
7969
"import \"fmt\"\n" +
8070
"func test(){fmt.Fprintln(<caret>)}", "fmt.Fprintln");
8171
}
82-
72+
8373
public void testVariableAutoImport() {
8474
doCheckResult("package main; \n" +
8575
"func test(){ErrNotSuppor<caret>}",
8676
"package main;\n" +
8777
"import \"net/http\"\n" +
8878
"func test(){http.ErrNotSupported}", "http.ErrNotSupported");
8979
}
90-
80+
9181
public void testConstantAutoImport() {
9282
doCheckResult("package main; \n" +
9383
"func test(){O_RDO<caret>}", "package main;\n" +
@@ -298,21 +288,55 @@ public void testDoNotCompleteExampleFunctions() throws IOException {
298288
myFixture.completeBasic();
299289
myFixture.checkResult("package a; func main() { _ = ExampleF<caret>");
300290
}
301-
291+
302292
public void testCompleteTestBenchmarkExamplesFromNonTestFiles() throws IOException {
303293
myFixture.getTempDirFixture().createFile("pack/pack.go", "package pack; func TestFoo() {} func BenchmarkFoo() {} func ExampleFoo() {}");
304294
myFixture.configureByText("my_test.go", "package a; func main() { _ = Foo<caret>");
305295
myFixture.completeBasic();
306296
assertContainsElements(myFixture.getLookupElementStrings(), "pack.TestFoo", "pack.BenchmarkFoo", "pack.ExampleFoo");
307297
}
308-
298+
309299
public void testDoNotAutoImportWithTheSameImportPath() throws IOException {
310300
myFixture.getTempDirFixture().createFile("pack1/file2.go", "package pack1; func MyFunctionFromSamePath() {}");
311301
myFixture.getTempDirFixture().createFile("pack2/file2.go", "package pack1; func MyFunctionFromOtherPath() {}");
312302
VirtualFile file = myFixture.getTempDirFixture().createFile("pack1/file1.go", "package pack1; func test() { pack1.MyFunc<caret> }");
313303
myFixture.configureFromExistingVirtualFile(file);
314304
myFixture.completeBasic();
315-
myFixture.checkResult("package pack1;\n" +
316-
"import \"pack2\" func test() { pack1.MyFunctionFromOtherPath() }");
305+
myFixture.checkResult("package pack1;\nimport \"pack2\" func test() { pack1.MyFunctionFromOtherPath() }");
317306
}
307+
308+
public void testAutoImportOwnImportPathFromTest() throws IOException {
309+
myFixture.getTempDirFixture().createFile("pack/a.go", "package myPack; func Func() {}");
310+
VirtualFile testFile = myFixture.getTempDirFixture()
311+
.createFile("pack/a_test.go", "package myPack_test; func TestFunc() { myPack.Fun<caret> }");
312+
myFixture.configureFromExistingVirtualFile(testFile);
313+
myFixture.completeBasic();
314+
myFixture.checkResult("package myPack_test;\nimport \"pack\" func TestFunc() { myPack.Func() }");
315+
}
316+
317+
public void testDoNotAutoImportDifferentPackageInSamePathFromTest() throws IOException {
318+
String text = "package foo_test; func TestFunc() { bar.Fun<caret> }";
319+
myFixture.getTempDirFixture().createFile("pack/a.go", "package bar; func Func() {}");
320+
myFixture.configureFromExistingVirtualFile(myFixture.getTempDirFixture().createFile("pack/a_test.go", text));
321+
myFixture.completeBasic();
322+
myFixture.checkResult(text);
323+
}
324+
325+
public void testImportOwnPathFromTestFile() throws IOException {
326+
TempDirTestFixture dir = myFixture.getTempDirFixture();
327+
VirtualFile testFile = dir.createFile("fuzz/fuzy_test.go", "package fuzy_test; import \"<caret>\"");
328+
myFixture.configureFromExistingVirtualFile(testFile);
329+
myFixture.completeBasic();
330+
assertContainsElements(myFixture.getLookupElementStrings(), "fuzz");
331+
}
332+
333+
public void testDoNotImportOwnPathFromNonTestPackage() throws IOException {
334+
TempDirTestFixture dir = myFixture.getTempDirFixture();
335+
VirtualFile testFile = dir.createFile("fuzz/fuzy_test.go", "package fuzy; import \"<caret>\"");
336+
myFixture.configureFromExistingVirtualFile(testFile);
337+
myFixture.completeBasic();
338+
List<String> strings = myFixture.getLookupElementStrings();
339+
assertTrue(strings != null && !strings.contains("fuzz"));
340+
}
341+
318342
}

0 commit comments

Comments
 (0)