Skip to content

Commit 24a6879

Browse files
committed
Merge branch 'import_path_from_test' of https://github.com/eugene-auduchinok/go-lang-idea-plugin into eugene-auduchinok-import_path_from_test
2 parents 345a687 + 996e095 commit 24a6879

File tree

11 files changed

+167
-39
lines changed

11 files changed

+167
-39
lines changed

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

Lines changed: 8 additions & 2 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;
@@ -38,6 +39,7 @@
3839
import com.intellij.openapi.ui.popup.JBPopupFactory;
3940
import com.intellij.openapi.util.Comparing;
4041
import com.intellij.openapi.util.TextRange;
42+
import com.intellij.openapi.util.text.StringUtil;
4143
import com.intellij.psi.PsiDirectory;
4244
import com.intellij.psi.PsiElement;
4345
import com.intellij.psi.PsiFile;
@@ -160,8 +162,11 @@ private Collection<String> getPackagesToImport(@NotNull PsiElement element) {
160162
if (myPackagesToImport == null) {
161163
final GlobalSearchScope scope = GoUtil.moduleScope(element);
162164
PsiFile file = element.getContainingFile();
163-
final PsiDirectory parentDirectory = file != null ? file.getParent() : null;
165+
boolean isTestFile = GoTestFinder.isTestFile(file) && GoTestFinder.isTestPackageName(((GoFile)file).getPackageName());
166+
final String packageName = isTestFile ? ((GoFile)file).getPackageNameWithoutTestSuffix() : null;
167+
final boolean allowSamePath = !StringUtil.isEmpty(packageName);
164168
Project project = element.getProject();
169+
final PsiDirectory parentDirectory = file != null ? file.getParent() : null;
165170
final GoExcludedPathsSettings excludedSettings = GoExcludedPathsSettings.getInstance(project);
166171
Collection<GoFile> es = StubIndex.getElements(GoPackagesIndex.KEY, myPackageName, project, scope, GoFile.class);
167172
myPackagesToImport = sorted(skipNulls(map2Set(
@@ -170,7 +175,8 @@ private Collection<String> getPackagesToImport(@NotNull PsiElement element) {
170175
@Nullable
171176
@Override
172177
public String fun(@NotNull GoFile file) {
173-
String importPath = parentDirectory == null || !parentDirectory.isEquivalentTo(file.getParent()) ? file.getImportPath() : null;
178+
String importPath = parentDirectory == null || !parentDirectory.isEquivalentTo(file.getParent()) ||
179+
(allowSamePath && packageName.equals(file.getPackageName())) ? file.getImportPath() : null;
174180
return importPath != null && !excludedSettings.isExcluded(importPath) ? importPath : null;
175181
}
176182
}

src/com/goide/completion/GoAutoImportCompletionContributor.java

Lines changed: 12 additions & 9 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,16 @@ 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();
90+
boolean isTestFile = GoTestFinder.isTestFile(file) && GoTestFinder.isTestPackageName(file.getPackageName());
91+
String allowedPackageInDirectory = isTestFile ? file.getPackageNameWithoutTestSuffix() : null;
8992
if (containingDirectory != null) {
90-
scope = new GoUtil.ExceptChildOfDirectory(containingDirectory, scope);
93+
scope = new GoUtil.ExceptChildOfDirectory(containingDirectory, scope, allowedPackageInDirectory);
9194
}
92-
Set<String> sortedKeys = sortMatching(matcher, StubIndex.getInstance().getAllKeys(ALL_PUBLIC_NAMES, project), ((GoFile)file));
95+
Set<String> sortedKeys = sortMatching(matcher, StubIndex.getInstance().getAllKeys(ALL_PUBLIC_NAMES, project), file);
9396
for (String name : sortedKeys) {
9497
processor.setName(name);
9598
StubIndex.getInstance().processElements(ALL_PUBLIC_NAMES, name, project, scope, GoNamedElement.class, processor);
@@ -313,11 +316,11 @@ private static Boolean cachedAllowed(@NotNull GoNamedElement element, @Nullable
313316

314317
private ExistingImportData cachedImportData(@NotNull GoNamedElement element, @Nullable ExistingImportData existingValue) {
315318
if (existingValue != null) return existingValue;
316-
319+
317320
GoFile declarationFile = element.getContainingFile();
318321
String importPath = declarationFile.getImportPath();
319322
GoImportSpec existingImport = myImportedPackages.get(importPath);
320-
323+
321324
boolean exists = existingImport != null;
322325
boolean isDot = exists && existingImport.isDot();
323326
String alias = existingImport != null ? existingImport.getAlias() : null;

src/com/goide/completion/GoImportPathsCompletionProvider.java

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,9 @@
1818

1919
import com.goide.GoFileType;
2020
import com.goide.project.GoExcludedPathsSettings;
21+
import com.goide.psi.GoFile;
2122
import com.goide.psi.GoImportString;
23+
import com.goide.runconfig.testing.GoTestFinder;
2224
import com.goide.sdk.GoSdkUtil;
2325
import com.goide.util.GoUtil;
2426
import com.intellij.codeInsight.completion.CompletionParameters;
@@ -31,6 +33,7 @@
3133
import com.intellij.openapi.util.text.StringUtil;
3234
import com.intellij.openapi.vfs.VirtualFile;
3335
import com.intellij.psi.PsiElement;
36+
import com.intellij.psi.PsiFile;
3437
import com.intellij.psi.search.FileTypeIndex;
3538
import com.intellij.psi.search.GlobalSearchScope;
3639
import com.intellij.psi.util.PsiTreeUtil;
@@ -62,11 +65,14 @@ public static void addCompletions(@NotNull CompletionResultSet result,
6265
String contextImportPath = GoCompletionUtil.getContextImportPath(context);
6366
GoExcludedPathsSettings excludedSettings = GoExcludedPathsSettings.getInstance(project);
6467
GlobalSearchScope scope = withLibraries ? GoUtil.moduleScope(module) : GoUtil.moduleScopeWithoutLibraries(module);
68+
PsiFile contextFile = context != null ? context.getContainingFile() : null;
69+
boolean isTestFile = GoTestFinder.isTestFile(contextFile) && GoTestFinder.isTestPackageName(((GoFile)contextFile).getPackageName());
6570
for (VirtualFile file : FileTypeIndex.getFiles(GoFileType.INSTANCE, scope)) {
6671
VirtualFile parent = file.getParent();
6772
if (parent == null) continue;
6873
String importPath = GoSdkUtil.getPathRelativeToSdkAndLibraries(parent, project, module);
69-
if (!StringUtil.isEmpty(importPath) && !importPath.equals(contextImportPath) && !excludedSettings.isExcluded(importPath)) {
74+
if (!StringUtil.isEmpty(importPath) && !excludedSettings.isExcluded(importPath) &&
75+
(!importPath.equals(contextImportPath) || isTestFile)) {
7076
result.addElement(GoCompletionUtil.createPackageLookupElement(importPath, contextImportPath, false));
7177
}
7278
}

src/com/goide/psi/GoFile.java

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -423,6 +423,12 @@ public String getPackageName() {
423423
return null;
424424
}
425425

426+
@Nullable
427+
public String getPackageNameWithoutTestSuffix() {
428+
String name = getPackageName();
429+
return name != null ? StringUtil.trimEnd(name, GoConstants.TEST_SUFFIX) : null;
430+
}
431+
426432
@Nullable
427433
@Override
428434
public GoFileStub getStub() {
@@ -492,5 +498,4 @@ public boolean value(PsiComment comment) {
492498
}
493499
});
494500
}
495-
496501
}

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

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,13 +39,17 @@ 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) {
4646
return file != null && file.getFileType() == GoFileType.INSTANCE && file.getNameWithoutExtension().endsWith(GoConstants.TEST_SUFFIX);
4747
}
4848

49+
public static boolean isTestPackageName(@Nullable String packageName) {
50+
return packageName != null && packageName.endsWith(GoConstants.TEST_SUFFIX);
51+
}
52+
4953
@Nullable
5054
public static String getTestFunctionName(@NotNull GoFunctionOrMethodDeclaration function) {
5155
return GoTestFunctionType.fromName(function.getName()) == GoTestFunctionType.TEST ? StringUtil.notNullize(function.getName()) : null;

src/com/goide/util/GoUtil.java

Lines changed: 12 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,24 @@ 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, @NotNull GlobalSearchScope baseScope, @Nullable String allowedPackageInExcludedDirectory) {
250252
super(baseScope);
251253
myParent = parent;
254+
myAllowedPackageInExcludedDirectory = allowedPackageInExcludedDirectory;
252255
}
253256

254257
@Override
255258
public boolean contains(@NotNull VirtualFile file) {
256-
return !myParent.equals(file.getParent()) && super.contains(file);
259+
Project project = getProject();
260+
PsiFile psiFile = project != null ? PsiManager.getInstance(project).findFile(file) : null;
261+
if (!(psiFile instanceof GoFile)) return false;
262+
263+
return (!myParent.equals(file.getParent()) ||
264+
myAllowedPackageInExcludedDirectory != null &&
265+
myAllowedPackageInExcludedDirectory.equals(((GoFile)psiFile).getPackageName())) &&
266+
super.contains(file);
257267
}
258268
}
259269

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: 25 additions & 17 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,14 +288,14 @@ 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() {}");
@@ -315,4 +305,22 @@ public void testDoNotAutoImportWithTheSameImportPath() throws IOException {
315305
myFixture.checkResult("package pack1;\n" +
316306
"import \"pack2\" func test() { pack1.MyFunctionFromOtherPath() }");
317307
}
308+
309+
public void testImportOwnPathFromTestFile() throws IOException {
310+
TempDirTestFixture dir = myFixture.getTempDirFixture();
311+
VirtualFile testFile = dir.createFile("fuzz/fuzy_test.go", "package fuzy_test; import \"<caret>\"");
312+
myFixture.configureFromExistingVirtualFile(testFile);
313+
myFixture.completeBasic();
314+
assertContainsElements(myFixture.getLookupElementStrings(), "fuzz");
315+
}
316+
317+
public void testDoNotImportOwnPathFromNonTestPackage() throws IOException {
318+
TempDirTestFixture dir = myFixture.getTempDirFixture();
319+
VirtualFile testFile = dir.createFile("fuzz/fuzy_test.go", "package fuzy; import \"<caret>\"");
320+
myFixture.configureFromExistingVirtualFile(testFile);
321+
myFixture.completeBasic();
322+
List<String> strings = myFixture.getLookupElementStrings();
323+
assertTrue(strings != null && !strings.contains("fuzz"));
324+
}
325+
318326
}
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
/*
2+
* Copyright 2013-2015 Sergey Ignatov, Alexander Zolotov, Florin Patan
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package com.goide.completion;
18+
19+
import com.intellij.testFramework.LightProjectDescriptor;
20+
21+
public abstract class GoCompletionSdkAwareTestBase extends GoCompletionTestBase {
22+
@Override
23+
public void setUp() throws Exception {
24+
super.setUp();
25+
setUpProjectSdk();
26+
}
27+
28+
@Override
29+
protected LightProjectDescriptor getProjectDescriptor() {
30+
return createMockProjectDescriptor();
31+
}
32+
}

0 commit comments

Comments
 (0)