Skip to content
This repository was archived by the owner on Nov 4, 2024. It is now read-only.

Commit 0869eb3

Browse files
Fix microsoft#24: 'Go to Definition' for relative imports not resolving directly to the appropriate module (microsoft#702)
* Fix microsoft#24: 'Go to Definition' for relative imports not resolving directly to the appropriate module * Add test
1 parent 6b57eff commit 0869eb3

File tree

3 files changed

+36
-1
lines changed

3 files changed

+36
-1
lines changed

src/Analysis/Ast/Impl/Analyzer/PythonAnalyzer.cs

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -369,7 +369,15 @@ public Task<ImmutableArray<ModuleKey>> FindDependenciesAsync(PythonAnalyzerEntry
369369
}
370370
break;
371371
case FromImportStatement fromImport:
372-
HandleSearchResults(isTypeshed, dependencies, moduleResolution, pathResolver.FindImports(module.FilePath, fromImport));
372+
var imports = pathResolver.FindImports(module.FilePath, fromImport);
373+
HandleSearchResults(isTypeshed, dependencies, moduleResolution, imports);
374+
if (imports is IImportChildrenSource childrenSource) {
375+
foreach (var name in fromImport.Names) {
376+
if (childrenSource.TryGetChildImport(name.Name, out var childImport)) {
377+
HandleSearchResults(isTypeshed, dependencies, moduleResolution, childImport);
378+
}
379+
}
380+
}
373381
break;
374382
}
375383
}

src/LanguageServer/Test/GoToDefinitionTests.cs

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,11 @@
1313
// See the Apache Version 2.0 License for specific language governing
1414
// permissions and limitations under the License.
1515

16+
using System;
17+
using System.IO;
1618
using System.Threading.Tasks;
1719
using FluentAssertions;
20+
using Microsoft.Python.Analysis.Documents;
1821
using Microsoft.Python.Core.Text;
1922
using Microsoft.Python.LanguageServer.Sources;
2023
using Microsoft.Python.LanguageServer.Tests.FluentAssertions;
@@ -161,5 +164,27 @@ class A(object):
161164
var reference = ds.FindDefinition(analysis, new SourceLocation(2, 12));
162165
reference.Should().BeNull();
163166
}
167+
168+
[TestMethod, Priority(0)]
169+
public async Task GotoRelativeImportInExplicitPackage() {
170+
var pkgPath = TestData.GetTestSpecificUri("pkg", "__init__.py");
171+
var modPath = TestData.GetTestSpecificUri("pkg", "mod.py");
172+
var subpkgPath = TestData.GetTestSpecificUri("pkg", "subpkg", "__init__.py");
173+
var submodPath = TestData.GetTestSpecificUri("pkg", "submod", "__init__.py");
174+
175+
var root = TestData.GetTestSpecificRootUri().AbsolutePath;
176+
await CreateServicesAsync(root, PythonVersions.LatestAvailable3X);
177+
var rdt = Services.GetService<IRunningDocumentTable>();
178+
179+
rdt.OpenDocument(pkgPath, string.Empty);
180+
rdt.OpenDocument(modPath, "hello = 'World'");
181+
rdt.OpenDocument(subpkgPath, string.Empty);
182+
var submod = rdt.OpenDocument(submodPath, "from .. import mod");
183+
184+
var analysis = await submod.GetAnalysisAsync(-1);
185+
var ds = new DefinitionSource();
186+
var reference = ds.FindDefinition(analysis, new SourceLocation(1, 18));
187+
reference.uri.Should().Be(modPath);
188+
}
164189
}
165190
}

src/UnitTests/Core/Impl/TestData.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,9 +80,11 @@ public static Uri[] GetNextModuleUris(int count) {
8080
}
8181

8282
public static Uri GetTestSpecificUri(string relativePath) => new Uri(GetTestSpecificPath(relativePath));
83+
public static Uri GetTestSpecificUri(params string[] parts) => new Uri(GetTestSpecificPath(parts));
8384
public static Uri GetTestSpecificRootUri() => TestRunScopeAsyncLocal.Value.RootUri;
8485

8586
public static string GetTestSpecificPath(string relativePath) => TestRunScopeAsyncLocal.Value.GetTestSpecificPath(relativePath);
87+
public static string GetTestSpecificPath(params string[] parts) => TestRunScopeAsyncLocal.Value.GetTestSpecificPath(Path.Combine(parts));
8688
public static string GetTestRelativePath(Uri uri) => TestRunScopeAsyncLocal.Value.GetTestRelativePath(uri);
8789
public static string GetDefaultModulePath() => TestRunScopeAsyncLocal.Value.GetDefaultModulePath();
8890
public static string GetNextModulePath() => TestRunScopeAsyncLocal.Value.GetNextModulePath();

0 commit comments

Comments
 (0)