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

NullReferenceException getting URI absolute path in PythonModule.Definition #1018

Closed
jakebailey opened this issue Apr 26, 2019 · 15 comments · Fixed by #1032
Closed

NullReferenceException getting URI absolute path in PythonModule.Definition #1018

jakebailey opened this issue Apr 26, 2019 · 15 comments · Fixed by #1032
Assignees
Labels
bug Something isn't working feature: references
Milestone

Comments

@jakebailey
Copy link
Member

   at Microsoft.Python.Core.UriExtensions.ToAbsolutePath(Uri uri)
   at Microsoft.Python.Analysis.Modules.PythonModule.get_Definition()
   at Microsoft.Python.LanguageServer.Sources.DefinitionSource.FromMember(IMember m)
   at Microsoft.Python.LanguageServer.Sources.DefinitionSource.FindDefinition(IDocumentAnalysis analysis, SourceLocation location, ILocatedMember& member)
   at Microsoft.Python.LanguageServer.Implementation.Server.GotoDefinition(TextDocumentPositionParams params, CancellationToken cancellationToken)
   at Microsoft.Python.LanguageServer.Implementation.LanguageServer.GotoDefinition(JToken token, CancellationToken cancellationToken)
   at Microsoft.Python.Core.UriExtensions.ToAbsolutePath(Uri uri)
   at Microsoft.Python.Analysis.Modules.PythonModule.get_Definition()
   at Microsoft.Python.LanguageServer.Sources.DefinitionSource.FromMember(IMember m)
   at Microsoft.Python.LanguageServer.Sources.DefinitionSource.FindDefinition(IDocumentAnalysis analysis, SourceLocation location, ILocatedMember& member)
   at Microsoft.Python.LanguageServer.Sources.ReferenceSource.FindAllReferencesAsync(Uri uri, SourceLocation location, ReferenceSearchOptions options, CancellationToken cancellationToken)
   at Microsoft.Python.LanguageServer.Implementation.LanguageServer.FindReferences(JToken token, CancellationToken cancellationToken)

Fix is likely one of:

  • Just do Uri?.ToAbsolutePath(); LocationInfo.FilePath is only ever used for comparison and is allowed to be null.
  • Pass in PythonModule.FilePath instead of converting Uri.
@jakebailey jakebailey added the bug Something isn't working label Apr 26, 2019
@AlexanderSher
Copy link
Contributor

Uri can be null only for SentinelModule.

@AlexanderSher
Copy link
Contributor

Do you have repro steps?

@jakebailey
Copy link
Member Author

For PythonModule, you mean? I wonder where the null is coming from, then. Even for untitled files, there will be a URI. Without line information I've been assuming that the URI is null, but it might be a member (Uri.LocalPath?).

I have no repro for this, unfortunately; these are pulled from telemetry.

@AlexanderSher
Copy link
Contributor

LocalPath doesn't return null. If Uri is null for any other type than SentinelModule, then we have a bug in some other place.

@MikhailArkhipov
Copy link

For Sentinel the Module?.Analysis.Ast would be null since it has empty analysis. Anyway, I'll add extra checks anyway.

@AlexanderSher
Copy link
Contributor

How is it possible to get Sentinel in FindDefinition?

@MikhailArkhipov
Copy link

Unresolved import?

@AlexanderSher
Copy link
Contributor

FindDefinition checks analysis?.Ast at the very beginning

            if (analysis?.Ast == null) {
                return null;
            }

So it won't proceed for unresolved import.

@MikhailArkhipov
Copy link

MikhailArkhipov commented May 1, 2019

Bunch of code checks FilePath for nulls so I guess there could be cases. Also, SpecializedModule. Ex

        public IPythonModule SpecializeModule(string name, Func<string, IPythonModule> specializationConstructor) {
            var import = CurrentPathResolver.GetModuleImportFromModuleName(name);
            var module = specializationConstructor(import?.ModulePath);
            _specialized[name] = module;
            return module;
        }

@AlexanderSher
Copy link
Contributor

AlexanderSher commented May 1, 2019

FilePath can be null, Uri can't.
SpecializedModule is abstract, its only derived class is TypingModule. So that would require TypingModule to be created with null or invalid path. Is it possible?

@MikhailArkhipov
Copy link

Technically yes

            var import = CurrentPathResolver.GetModuleImportFromModuleName(name);
            var module = specializationConstructor(import?.ModulePath);

such as we didn't find typing

@MikhailArkhipov
Copy link

And in PythonVariableModule

public Uri Uri => Module?.Uri;

@AlexanderSher
Copy link
Contributor

Then we should probably fail in this place: if module path isn't found, there is no reason to specialize it.

@MikhailArkhipov
Copy link

But this

        public PythonVariableModule(string name, IPythonInterpreter interpreter)
            : base(PythonMemberType.Module) {
            Name = name;
            Interpreter = interpreter;
            SetDeclaringModule(this);
        }

called from

        private PythonVariableModule GetOrCreateVariableModule(in string fullName, in PythonVariableModule parentModule, in string memberName) {
            if (_variableModules.TryGetValue(fullName, out var variableModule)) {
                return variableModule;
            }

            variableModule = new PythonVariableModule(fullName, Interpreter);

creates module with no Module and hence no URI

@AlexanderSher
Copy link
Contributor

PythonVariableModule without Module means that it is actually a package. So we shouldn't get into searching for module members in first place.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
bug Something isn't working feature: references
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants