Skip to content
This repository was archived by the owner on Apr 14, 2022. It is now read-only.

Fix #24: 'Go to Definition' for relative imports not resolving directly to the appropriate module #702

Merged
merged 2 commits into from
Mar 6, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 9 additions & 1 deletion src/Analysis/Ast/Impl/Analyzer/PythonAnalyzer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -356,7 +356,15 @@ public Task<ImmutableArray<ModuleKey>> FindDependenciesAsync(PythonAnalyzerEntry
}
break;
case FromImportStatement fromImport:
HandleSearchResults(isTypeshed, dependencies, moduleResolution, pathResolver.FindImports(module.FilePath, fromImport));
var imports = pathResolver.FindImports(module.FilePath, fromImport);
HandleSearchResults(isTypeshed, dependencies, moduleResolution, imports);
if (imports is IImportChildrenSource childrenSource) {
foreach (var name in fromImport.Names) {
if (childrenSource.TryGetChildImport(name.Name, out var childImport)) {
HandleSearchResults(isTypeshed, dependencies, moduleResolution, childImport);
}
}
}
break;
}
}
Expand Down
25 changes: 25 additions & 0 deletions src/LanguageServer/Test/GoToDefinitionTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,11 @@
// See the Apache Version 2.0 License for specific language governing
// permissions and limitations under the License.

using System;
using System.IO;
using System.Threading.Tasks;
using FluentAssertions;
using Microsoft.Python.Analysis.Documents;
using Microsoft.Python.Core.Text;
using Microsoft.Python.LanguageServer.Sources;
using Microsoft.Python.LanguageServer.Tests.FluentAssertions;
Expand Down Expand Up @@ -161,5 +164,27 @@ class A(object):
var reference = ds.FindDefinition(analysis, new SourceLocation(2, 12));
reference.Should().BeNull();
}

[TestMethod, Priority(0)]
public async Task GotoRelativeImportInExplicitPackage() {
var pkgPath = TestData.GetTestSpecificUri("pkg", "__init__.py");
var modPath = TestData.GetTestSpecificUri("pkg", "mod.py");
var subpkgPath = TestData.GetTestSpecificUri("pkg", "subpkg", "__init__.py");
var submodPath = TestData.GetTestSpecificUri("pkg", "submod", "__init__.py");

var root = TestData.GetTestSpecificRootUri().AbsolutePath;
await CreateServicesAsync(root, PythonVersions.LatestAvailable3X);
var rdt = Services.GetService<IRunningDocumentTable>();

rdt.OpenDocument(pkgPath, string.Empty);
rdt.OpenDocument(modPath, "hello = 'World'");
rdt.OpenDocument(subpkgPath, string.Empty);
var submod = rdt.OpenDocument(submodPath, "from .. import mod");

var analysis = await submod.GetAnalysisAsync(-1);
var ds = new DefinitionSource();
var reference = ds.FindDefinition(analysis, new SourceLocation(1, 18));
reference.uri.Should().Be(modPath);
}
}
}
2 changes: 2 additions & 0 deletions src/UnitTests/Core/Impl/TestData.cs
Original file line number Diff line number Diff line change
Expand Up @@ -80,9 +80,11 @@ public static Uri[] GetNextModuleUris(int count) {
}

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

public static string GetTestSpecificPath(string relativePath) => TestRunScopeAsyncLocal.Value.GetTestSpecificPath(relativePath);
public static string GetTestSpecificPath(params string[] parts) => TestRunScopeAsyncLocal.Value.GetTestSpecificPath(Path.Combine(parts));
public static string GetTestRelativePath(Uri uri) => TestRunScopeAsyncLocal.Value.GetTestRelativePath(uri);
public static string GetDefaultModulePath() => TestRunScopeAsyncLocal.Value.GetDefaultModulePath();
public static string GetNextModulePath() => TestRunScopeAsyncLocal.Value.GetNextModulePath();
Expand Down