VSCode build of the analysis engine#3957
VSCode build of the analysis engine#3957MikhailArkhipov merged 73 commits intomicrosoft:masterfrom MikhailArkhipov:vsc
Conversation
| <PackageReference Include="NewtonSoft.Json" Version="10.0.1" /> | ||
| <PackageReference Include="Python2" version="2.7.14" Condition="'$(OS)' == 'Windows_NT'" /> | ||
| <PackageReference Include="Python" version="3.6.4" Condition="'$(OS)' == 'Windows_NT'" /> | ||
| </ItemGroup> <ItemGroup> |
| public void Kill() { | ||
| try { | ||
| _process?.Kill(); | ||
| if (!_process.HasExited) { |
There was a problem hiding this comment.
_process?.Kill() has null check. Do we need it here as well?
| // VS Code always sends /-based paths. Also, its file URL looks like | ||
| // file:///C:/foo which yields AbsolutePath as /C:/foo which is wrong. | ||
| // We need to clean this up. | ||
| var path = WebUtility.UrlDecode(uri.AbsolutePath).Replace('/', '\\'); |
There was a problem hiding this comment.
We should use LocalPath to extract local paths, not AbsolutePath. (If there are path forms that do not work well with LocalPath, we can special case those. But the normal case works fine.)
There was a problem hiding this comment.
OK. LocalPath still needs to be cleaned up. It looks like /f:/VSCP/src/test/pythonFiles
| try { | ||
| exitCode = proc.Wait(60000); | ||
| } catch (Exception ex) { | ||
| fact.Log(TraceLevel.Error, $"ScrapeException {ex.Message}", proc.FileName, proc.Arguments); |
There was a problem hiding this comment.
Put the exception message as its own field. It makes processing the log file easier.
| } catch (ArgumentException) { | ||
| Version = new Version(); | ||
| } catch (FormatException) { | ||
| } catch (Exception ex) when (ex is ArgumentException || ex is ArgumentNullException || ex is FormatException) { |
There was a problem hiding this comment.
Doesn't ex is ArgumentException imply that it is also ArgumentNullException?
|
|
||
| // Based on https://github.com/Microsoft/vscode-python/blob/master/src/client/common/markdown/restTextConverter.ts | ||
|
|
||
| namespace Microsoft.PythonTools.Analysis.LanguageServer { |
There was a problem hiding this comment.
Let's bump this up to Microsoft.PythonTools.Analysis. It isn't directly related to the language server.
| internal readonly ParseQueue _parseQueue; | ||
| private readonly Dictionary<IDocument, VolatileCounter> _pendingParse; | ||
| private readonly VolatileCounter _pendingAnalysisEnqueue; | ||
| private readonly RestTextConverter _textConverter = new RestTextConverter(); |
There was a problem hiding this comment.
If this is not stateful, can we have a static instance? If it is stateful, we should instantiate it when needed (it looks cheap enough).
There was a problem hiding this comment.
Technically it has states as it is converting. Not that it is called from multiple threads concurrently, but theoretically it could.
There was a problem hiding this comment.
Okay, let's instantiate it for each conversion, just to be safe.
| // It is called from DidChangeTextDocument which must fully finish | ||
| // since otherwise Complete() may come before the change is enqueued | ||
| // for processing and the completion list will be driven off the stale data. | ||
| cookieTask.ContinueWith(t => { |
There was a problem hiding this comment.
For the sake of indentation, can we extract this lambda to its own function ("FinishParse" or similar)? At least for the non-faulting case.
| private PythonAst GetParseTree(IPythonProjectEntry entry, Uri documentUri, out int? version) { | ||
| version = null; | ||
| PythonAst tree = null; | ||
| var parse = entry.WaitForCurrentParse(_clientCaps?.python?.completionsTimeout ?? Timeout.Infinite, CancellationToken); |
There was a problem hiding this comment.
Completions may not be the only timeout we want here (e.g. we have a longer timeout for hover in VS today). This may need to be a parameter
| RegexOptions.CultureInvariant | RegexOptions.IgnoreCase); | ||
| private static readonly Regex PythonBinaryRegex = new Regex(@"^(?!\d)(?<name>(\w|_)+)\.((\w|_|-)+?\.)?pyd$", | ||
| private static readonly Regex PythonBinaryRegex = new Regex(@"^(?!\d)(?<name>(\w|_)+)\.((\w|_|-)+?\.)?(pyd|so|dyLib)$", | ||
| RegexOptions.CultureInvariant | RegexOptions.IgnoreCase); |
There was a problem hiding this comment.
This (and below) regex ignore case - does that need to change for other OS?
There was a problem hiding this comment.
I think so and dyLib cover OSX and Linux
| // package (checked by module name first, then sanity-checked by path), and register any that match. | ||
| if (ModulePath.IsInitPyFile(FilePath)) { | ||
| string pathPrefix = Path.GetDirectoryName(FilePath) + "\\"; | ||
| string pathPrefix = Path.GetDirectoryName(FilePath) + Path.DirectorySeparatorChar; |
| <!-- Nuget packaging --> | ||
| <PropertyGroup> | ||
| <NuGetPackageRoot Condition=" '$(NuGetPackageRoot)' == '' ">$(UserProfile)\.nuget\packages\</NuGetPackageRoot> | ||
| <NugetPackageVersion>0.1.0</NugetPackageVersion> |
There was a problem hiding this comment.
Is this something we should promote to a build property?
|
And when we merge this, we should do a squash merge :) |
| if (SafeGetProcessById(pid) == null) { | ||
| Environment.Exit(0); | ||
| } | ||
| Thread.Sleep(5000); |
There was a problem hiding this comment.
await Task.Delay(5000)
And you can pass CancellationToken
|
|
||
| [JsonRpcMethod("textDocument/didChange")] | ||
| public Task DidChangeTextDocument(JToken token) | ||
| public void DidChangeTextDocument(JToken token) |
There was a problem hiding this comment.
Sort of. Call comes from VSC process over RPC. StreamJsonRPC handles is async or plain depending on the signature.
There was a problem hiding this comment.
I'm just thinking if this method can become async in future version of API
|
|
||
| #if WAIT_FOR_DEBUGGER | ||
| while (!System.Diagnostics.Debugger.IsAttached) { | ||
| Thread.Sleep(1000); |
There was a problem hiding this comment.
await Task.Delay(1000)
There was a problem hiding this comment.
It's current in Program.cs which is not async
| diagnostics = e.diagnostics.ToArray() | ||
| }; | ||
| _rpc.InvokeAsync("textDocument/publishDiagnostics", parameters); | ||
| _vscode.NotifyWithParameterObjectAsync("textDocument/publishDiagnostics", parameters); |
|
|
||
| public IPythonParse WaitForCurrentParse(int timeout = -1) { | ||
| if (!_pendingParse.Wait(timeout)) { | ||
| public IPythonParse WaitForCurrentParse(int timeout, CancellationToken token) { |
There was a problem hiding this comment.
Can we make this method async?
There was a problem hiding this comment.
I'd rather not. This is only ever used in contexts where blocking briefly (and it's only a parse, so it's brief) is the right action.
There was a problem hiding this comment.
How many times GetCompletions can be called while we're waiting for a parse?
| @@ -0,0 +1,74 @@ | |||
| <Project> | |||
There was a problem hiding this comment.
Unused, but keeping it around in case we want to pre-scrape on Mac
|
|
||
| [Serializable] | ||
| public struct ShowMessageRequestParams { | ||
| public class ShowMessageRequestParams { |
There was a problem hiding this comment.
You have converted some of the structs into classes. Does it matter only for those several types?
There was a problem hiding this comment.
Those which are important are the JSON serialization. Others can remain structs.
|
Some of the files have disappeared from the PR. Is it intentional? |
|
|
||
| namespace Microsoft.PythonTools.Analysis.Infrastructure { | ||
| static class TaskExtensions { | ||
| public static class TaskExtensions { |
There was a problem hiding this comment.
Does this need to be public? InternalsVisibleTo is preferable.
There was a problem hiding this comment.
They are generally useful extensions but up to you. @AlexanderSher - your opinion?
| using System.Net; | ||
|
|
||
| namespace Microsoft.PythonTools.Analysis.Infrastructure { | ||
| public static class UriExtensions { |
|
|
||
| // For pending changes, we use alternate comparer that checks #fragment | ||
| private readonly ConcurrentDictionary<Uri, List<DidChangeTextDocumentParams>> _pendingChanges; | ||
| private ManualResetEventSlim _documentChangeProcessingComplete = new ManualResetEventSlim(true); |
|
Branch was squished, had to restore some changes |
|
See also microsoft/vscode-python#1231 |
|
Generally useful does not mean we make them public supported API. This assembly is public/supported now, so we only want things to be public when it’s deliberate.
|
|
OK, made internal |
|
|
Common.Build.Core.settingsRestTextConverter) (will ports tests next)completionrequestsoanddyLibPython compiled modules