未验证 提交 561df893 编写于 作者: D dotnet-automerge-bot 提交者: GitHub

Merge pull request #26882 from dotnet/merges/dev15.7.x-to-dev15.7.x-vs-deps

Merge dev15.7.x to dev15.7.x-vs-deps
......@@ -101,7 +101,8 @@ public void TestChangedTextWithMultipleUnorderedChanges()
new TextChange(new TextSpan(0, 5), "Halo")
};
Assert.Throws<ArgumentException>(() => text.WithChanges(changes));
var newText = text.WithChanges(changes);
Assert.Equal("Halo Universe", newText.ToString());
}
[Fact]
......@@ -138,8 +139,8 @@ public void TestChangedTextWithReplaceBeforeInsertSamePosition()
new TextChange(new TextSpan(6, 0), "Super ")
};
// this causes overlap
Assert.Throws<ArgumentException>(() => text.WithChanges(changes));
var newText = text.WithChanges(changes);
Assert.Equal("Hello Super Vurld", newText.ToString());
}
[Fact]
......
......@@ -306,11 +306,11 @@ internal class CodeAnalysisResources {
}
/// <summary>
/// Looks up a localized string similar to The changes must be ordered and not overlapping..
/// Looks up a localized string similar to The changes must not overlap..
/// </summary>
internal static string ChangesMustBeOrderedAndNotOverlapping {
internal static string ChangesMustNotOverlap {
get {
return ResourceManager.GetString("ChangesMustBeOrderedAndNotOverlapping", resourceCulture);
return ResourceManager.GetString("ChangesMustNotOverlap", resourceCulture);
}
}
......
......@@ -413,8 +413,8 @@
<data name="PEImageDoesntContainManagedMetadata" xml:space="preserve">
<value>PE image doesn't contain managed metadata.</value>
</data>
<data name="ChangesMustBeOrderedAndNotOverlapping" xml:space="preserve">
<value>The changes must be ordered and not overlapping.</value>
<data name="ChangesMustNotOverlap" xml:space="preserve">
<value>The changes must not overlap.</value>
</data>
<data name="DiagnosticIdCantBeNullOrWhitespace" xml:space="preserve">
<value>A DiagnosticDescriptor must have an Id that is neither null nor an empty string nor a string that only contains white space.</value>
......
......@@ -633,7 +633,19 @@ public virtual SourceText WithChanges(IEnumerable<TextChange> changes)
// there can be no overlapping changes
if (change.Span.Start < position)
{
throw new ArgumentException(CodeAnalysisResources.ChangesMustBeOrderedAndNotOverlapping, nameof(changes));
// Handle the case of unordered changes by sorting the input and retrying. This is inefficient, but
// downstream consumers have been known to hit this case in the past and we want to avoid crashes.
// https://github.com/dotnet/roslyn/pull/26339
if (change.Span.End <= changeRanges.Last().Span.Start)
{
changes = (from c in changes
where !c.Span.IsEmpty || c.NewText?.Length > 0
orderby c.Span
select c).ToList();
return WithChanges(changes);
}
throw new ArgumentException(CodeAnalysisResources.ChangesMustNotOverlap, nameof(changes));
}
var newTextLength = change.NewText?.Length ?? 0;
......
......@@ -496,9 +496,9 @@
<target state="translated">Image PE neobsahuje spravovaná metadata.</target>
<note />
</trans-unit>
<trans-unit id="ChangesMustBeOrderedAndNotOverlapping">
<source>The changes must be ordered and not overlapping.</source>
<target state="translated">Změny musí být seřazené a nesmí se překrývat.</target>
<trans-unit id="ChangesMustNotOverlap">
<source>The changes must not overlap.</source>
<target state="needs-review-translation">Změny musí být seřazené a nesmí se překrývat.</target>
<note />
</trans-unit>
<trans-unit id="DiagnosticIdCantBeNullOrWhitespace">
......
......@@ -496,9 +496,9 @@
<target state="translated">PE-Abbild enthält keine verwalteten Metadaten.</target>
<note />
</trans-unit>
<trans-unit id="ChangesMustBeOrderedAndNotOverlapping">
<source>The changes must be ordered and not overlapping.</source>
<target state="translated">Die Änderungen müssen sortiert sein und dürfen sich nicht überschneiden.</target>
<trans-unit id="ChangesMustNotOverlap">
<source>The changes must not overlap.</source>
<target state="needs-review-translation">Die Änderungen müssen sortiert sein und dürfen sich nicht überschneiden.</target>
<note />
</trans-unit>
<trans-unit id="DiagnosticIdCantBeNullOrWhitespace">
......
......@@ -496,9 +496,9 @@
<target state="translated">La imagen PE no contiene metadatos administrados.</target>
<note />
</trans-unit>
<trans-unit id="ChangesMustBeOrderedAndNotOverlapping">
<source>The changes must be ordered and not overlapping.</source>
<target state="translated">Los cambios deben estar ordenados y no superponerse.</target>
<trans-unit id="ChangesMustNotOverlap">
<source>The changes must not overlap.</source>
<target state="needs-review-translation">Los cambios deben estar ordenados y no superponerse.</target>
<note />
</trans-unit>
<trans-unit id="DiagnosticIdCantBeNullOrWhitespace">
......
......@@ -496,9 +496,9 @@
<target state="translated">L'image PE ne contient pas de métadonnées gérées.</target>
<note />
</trans-unit>
<trans-unit id="ChangesMustBeOrderedAndNotOverlapping">
<source>The changes must be ordered and not overlapping.</source>
<target state="translated">Les modifications doivent être ordonnées et ne pas se chevaucher.</target>
<trans-unit id="ChangesMustNotOverlap">
<source>The changes must not overlap.</source>
<target state="needs-review-translation">Les modifications doivent être ordonnées et ne pas se chevaucher.</target>
<note />
</trans-unit>
<trans-unit id="DiagnosticIdCantBeNullOrWhitespace">
......
......@@ -496,9 +496,9 @@
<target state="translated">L'immagine PE non contiene metadati gestiti.</target>
<note />
</trans-unit>
<trans-unit id="ChangesMustBeOrderedAndNotOverlapping">
<source>The changes must be ordered and not overlapping.</source>
<target state="translated">Le modifiche devono essere ordinate e non sovrapposte.</target>
<trans-unit id="ChangesMustNotOverlap">
<source>The changes must not overlap.</source>
<target state="needs-review-translation">Le modifiche devono essere ordinate e non sovrapposte.</target>
<note />
</trans-unit>
<trans-unit id="DiagnosticIdCantBeNullOrWhitespace">
......
......@@ -496,9 +496,9 @@
<target state="translated">PE イメージには、管理されたメタデータが含まれていません。</target>
<note />
</trans-unit>
<trans-unit id="ChangesMustBeOrderedAndNotOverlapping">
<source>The changes must be ordered and not overlapping.</source>
<target state="translated">変更は順序付けする必要があり、重複は許可されません。</target>
<trans-unit id="ChangesMustNotOverlap">
<source>The changes must not overlap.</source>
<target state="needs-review-translation">変更は順序付けする必要があり、重複は許可されません。</target>
<note />
</trans-unit>
<trans-unit id="DiagnosticIdCantBeNullOrWhitespace">
......
......@@ -496,9 +496,9 @@
<target state="translated">PE 이미지에 관리된 메타데이터가 포함되어 있지 않습니다.</target>
<note />
</trans-unit>
<trans-unit id="ChangesMustBeOrderedAndNotOverlapping">
<source>The changes must be ordered and not overlapping.</source>
<target state="translated">변경 내용의 순서를 지정해야 하고 겹쳐서는 안 됩니다.</target>
<trans-unit id="ChangesMustNotOverlap">
<source>The changes must not overlap.</source>
<target state="needs-review-translation">변경 내용의 순서를 지정해야 하고 겹쳐서는 안 됩니다.</target>
<note />
</trans-unit>
<trans-unit id="DiagnosticIdCantBeNullOrWhitespace">
......
......@@ -496,9 +496,9 @@
<target state="translated">Obraz PE nie zawiera zarządzanych metadanych.</target>
<note />
</trans-unit>
<trans-unit id="ChangesMustBeOrderedAndNotOverlapping">
<source>The changes must be ordered and not overlapping.</source>
<target state="translated">Zmiany muszą być uporządkowane i nie mogą nakładać się na siebie.</target>
<trans-unit id="ChangesMustNotOverlap">
<source>The changes must not overlap.</source>
<target state="needs-review-translation">Zmiany muszą być uporządkowane i nie mogą nakładać się na siebie.</target>
<note />
</trans-unit>
<trans-unit id="DiagnosticIdCantBeNullOrWhitespace">
......
......@@ -496,9 +496,9 @@
<target state="translated">Imagem PE não contém metadados gerenciados.</target>
<note />
</trans-unit>
<trans-unit id="ChangesMustBeOrderedAndNotOverlapping">
<source>The changes must be ordered and not overlapping.</source>
<target state="translated">As alterações devem ser ordenadas e não sobrepostas.</target>
<trans-unit id="ChangesMustNotOverlap">
<source>The changes must not overlap.</source>
<target state="needs-review-translation">As alterações devem ser ordenadas e não sobrepostas.</target>
<note />
</trans-unit>
<trans-unit id="DiagnosticIdCantBeNullOrWhitespace">
......
......@@ -496,9 +496,9 @@
<target state="translated">Образ среды предустановки не содержит управляемые метаданные.</target>
<note />
</trans-unit>
<trans-unit id="ChangesMustBeOrderedAndNotOverlapping">
<source>The changes must be ordered and not overlapping.</source>
<target state="translated">Изменения должны идти в строгом порядке и не накладываться.</target>
<trans-unit id="ChangesMustNotOverlap">
<source>The changes must not overlap.</source>
<target state="needs-review-translation">Изменения должны идти в строгом порядке и не накладываться.</target>
<note />
</trans-unit>
<trans-unit id="DiagnosticIdCantBeNullOrWhitespace">
......
......@@ -496,9 +496,9 @@
<target state="translated">PE görüntüsü yönetilen meta verileri içermiyor.</target>
<note />
</trans-unit>
<trans-unit id="ChangesMustBeOrderedAndNotOverlapping">
<source>The changes must be ordered and not overlapping.</source>
<target state="translated">Değişiklikler sıralanmalı ve çakışmamalıdır.</target>
<trans-unit id="ChangesMustNotOverlap">
<source>The changes must not overlap.</source>
<target state="needs-review-translation">Değişiklikler sıralanmalı ve çakışmamalıdır.</target>
<note />
</trans-unit>
<trans-unit id="DiagnosticIdCantBeNullOrWhitespace">
......
......@@ -496,9 +496,9 @@
<target state="translated">PE 映像不包含任何托管元数据。</target>
<note />
</trans-unit>
<trans-unit id="ChangesMustBeOrderedAndNotOverlapping">
<source>The changes must be ordered and not overlapping.</source>
<target state="translated">更改必须有序且不重叠。</target>
<trans-unit id="ChangesMustNotOverlap">
<source>The changes must not overlap.</source>
<target state="needs-review-translation">更改必须有序且不重叠。</target>
<note />
</trans-unit>
<trans-unit id="DiagnosticIdCantBeNullOrWhitespace">
......
......@@ -496,9 +496,9 @@
<target state="translated">PE 映像不包含 Managed 中繼資料。</target>
<note />
</trans-unit>
<trans-unit id="ChangesMustBeOrderedAndNotOverlapping">
<source>The changes must be ordered and not overlapping.</source>
<target state="translated">變更必須排序且不可重疊。</target>
<trans-unit id="ChangesMustNotOverlap">
<source>The changes must not overlap.</source>
<target state="needs-review-translation">變更必須排序且不可重疊。</target>
<note />
</trans-unit>
<trans-unit id="DiagnosticIdCantBeNullOrWhitespace">
......
......@@ -137,8 +137,8 @@ public IInteractiveWindow CurrentWindow
_currentWindow = value;
_workspace.Window = value;
_interactiveHost.Output = _currentWindow.OutputWriter;
_interactiveHost.ErrorOutput = _currentWindow.ErrorOutputWriter;
_interactiveHost.SetOutput( _currentWindow.OutputWriter);
_interactiveHost.SetErrorOutput(_currentWindow.ErrorOutputWriter);
_currentWindow.SubmissionBufferAdded += SubmissionBufferAdded;
_interactiveCommands = _commandsFactory.CreateInteractiveCommands(_currentWindow, CommandPrefix, _commands);
......@@ -171,8 +171,8 @@ private IInteractiveWindow GetCurrentWindowOrThrow()
public Task<ExecutionResult> InitializeAsync()
{
var window = GetCurrentWindowOrThrow();
_interactiveHost.Output = window.OutputWriter;
_interactiveHost.ErrorOutput = window.ErrorOutputWriter;
_interactiveHost.SetOutput(window.OutputWriter);
_interactiveHost.SetErrorOutput(window.ErrorOutputWriter);
return ResetAsyncWorker();
}
......
......@@ -81,8 +81,8 @@ private async Task<InitializedRemoteService> TryStartAndInitializeProcessAsync(C
if (!initializationResult.Success)
{
remoteService.Dispose(joinThreads: false);
Host.ReportProcessExited(remoteService.Process);
remoteService.Dispose(joinThreads: false);
return default(InitializedRemoteService);
}
......
......@@ -74,9 +74,14 @@ private async void ProcessExitedHandler(object _, EventArgs __)
_processExitHandlerStatus = ProcessExitHandlerStatus.Handled;
// Should set _processExitHandlerStatus before calling OnProcessExited to avoid deadlocks.
// Calling the host should be within the lock to prevent its disposing during the execution.
await _host.OnProcessExited(Process).ConfigureAwait(false);
}
}
var host = _host;
if (host != null)
{
await host.OnProcessExited(Process).ConfigureAwait(false);
}
}
catch (Exception e) when (FatalError.Report(e))
{
......@@ -114,19 +119,17 @@ private void ReadOutput(bool error)
}
}
// Dispose may called anytime.
internal void Dispose(bool joinThreads)
{
// There can be a call from host initiated from OnProcessExit.
// This check on the beginning helps to avoid a reentrancy.
if (_processExitHandlerStatus == ProcessExitHandlerStatus.Hooked)
// We should not proceed with disposing if _disposeSemaphore is locked.
using (_disposeSemaphore.DisposableWait())
{
using (_disposeSemaphore.DisposableWait())
if (_processExitHandlerStatus == ProcessExitHandlerStatus.Hooked)
{
if (_processExitHandlerStatus == ProcessExitHandlerStatus.Hooked)
{
Process.Exited -= ProcessExitedHandler;
_processExitHandlerStatus = ProcessExitHandlerStatus.Handled;
}
Process.Exited -= ProcessExitedHandler;
_processExitHandlerStatus = ProcessExitHandlerStatus.Handled;
}
}
......
......@@ -40,6 +40,8 @@ internal sealed partial class InteractiveHost : MarshalByRefObject
private TextWriter _output;
private TextWriter _errorOutput;
private readonly object _outputGuard;
private readonly object _errorOutputGuard;
internal event Action<bool> ProcessStarting;
......@@ -55,6 +57,8 @@ internal sealed partial class InteractiveHost : MarshalByRefObject
_replServiceProviderType = replServiceProviderType;
_hostPath = hostPath;
_initialWorkingDirectory = workingDirectory;
_outputGuard = new object();
_errorOutputGuard = new object();
var serverProvider = new BinaryServerFormatterSinkProvider { TypeFilterLevel = TypeFilterLevel.Full };
_serverChannel = new IpcServerChannel(GenerateUniqueChannelLocalName(), "ReplChannel-" + Guid.NewGuid(), serverProvider);
......@@ -69,9 +73,9 @@ internal sealed partial class InteractiveHost : MarshalByRefObject
internal Process TryGetProcess()
{
InitializedRemoteService initializedService;
return (_lazyRemoteService?.InitializedService != null &&
_lazyRemoteService.InitializedService.TryGetValue(out initializedService)) ? initializedService.ServiceOpt.Process : null;
var lazyRemoteService = _lazyRemoteService;
return (lazyRemoteService?.InitializedService != null &&
lazyRemoteService.InitializedService.TryGetValue(out initializedService)) ? initializedService.ServiceOpt.Process : null;
}
internal Service TryGetService()
......@@ -167,7 +171,11 @@ private RemoteService TryStartProcess(CultureInfo culture, CancellationToken can
return null;
}
_output.WriteLine(FeaturesResources.Attempt_to_connect_to_process_Sharp_0_failed_retrying, newProcessId);
lock (_outputGuard)
{
_output.WriteLine(FeaturesResources.Attempt_to_connect_to_process_Sharp_0_failed_retrying, newProcessId);
}
cancellationToken.ThrowIfCancellationRequested();
}
......@@ -212,8 +220,12 @@ private bool CheckAlive(Process process)
bool alive = process.IsAlive();
if (!alive)
{
_errorOutput.WriteLine(FeaturesResources.Failed_to_launch_0_process_exit_code_colon_1_with_output_colon, _hostPath, process.ExitCode);
_errorOutput.WriteLine(process.StandardError.ReadToEnd());
string errorString = process.StandardError.ReadToEnd();
lock (_errorOutputGuard)
{
_errorOutput.WriteLine(FeaturesResources.Failed_to_launch_0_process_exit_code_colon_1_with_output_colon, _hostPath, process.ExitCode);
_errorOutput.WriteLine(errorString);
}
}
return alive;
......@@ -224,9 +236,12 @@ private bool CheckAlive(Process process)
DisposeRemoteService(disposing: false);
}
// Dispose may be called anytime.
public void Dispose()
{
DisposeChannel();
SetOutput(TextWriter.Null);
SetErrorOutput(TextWriter.Null);
DisposeRemoteService(disposing: true);
GC.SuppressFinalize(this);
}
......@@ -249,41 +264,31 @@ private void DisposeChannel()
}
}
public TextWriter Output
public void SetOutput(TextWriter value)
{
get
if (value == null)
{
return _output;
throw new ArgumentNullException(nameof(value));
}
set
lock(_outputGuard)
{
if (value == null)
{
throw new ArgumentNullException(nameof(value));
}
var oldOutput = Interlocked.Exchange(ref _output, value);
oldOutput.Flush();
_output.Flush();
_output = value;
}
}
public TextWriter ErrorOutput
public void SetErrorOutput(TextWriter value)
{
get
if (value == null)
{
return _errorOutput;
throw new ArgumentNullException(nameof(value));
}
set
lock(_errorOutputGuard)
{
if (value == null)
{
throw new ArgumentNullException(nameof(value));
}
var oldOutput = Interlocked.Exchange(ref _errorOutput, value);
oldOutput.Flush();
_errorOutput.Flush();
_errorOutput = value;
}
}
......@@ -291,8 +296,12 @@ internal void OnOutputReceived(bool error, char[] buffer, int count)
{
(error ? ErrorOutputReceived : OutputReceived)?.Invoke(buffer, count);
var writer = error ? ErrorOutput : Output;
writer.Write(buffer, 0, count);
var writer = error ? _errorOutput : _output;
var guard = error ? _errorOutputGuard : _outputGuard;
lock (guard)
{
writer.Write(buffer, 0, count);
}
}
private LazyRemoteService CreateRemoteService(InteractiveHostOptions options, bool skipInitialization)
......@@ -320,7 +329,10 @@ private void ReportProcessExited(Process process)
if (exitCode.HasValue)
{
_errorOutput.WriteLine(FeaturesResources.Hosting_process_exited_with_exit_code_0, exitCode.Value);
lock (_errorOutputGuard)
{
_errorOutput.WriteLine(FeaturesResources.Hosting_process_exited_with_exit_code_0, exitCode.Value);
}
}
}
......@@ -330,11 +342,14 @@ private async Task<InitializedRemoteService> TryGetOrCreateRemoteServiceAsync(bo
{
LazyRemoteService currentRemoteService = _lazyRemoteService;
// disposed or not reset:
Debug.Assert(currentRemoteService != null);
for (int attempt = 0; attempt < MaxAttemptsToCreateProcess; attempt++)
{
// Remote service may be disposed anytime.
if (currentRemoteService == null)
{
return default;
}
var initializedService = await currentRemoteService.InitializedService.GetValueAsync(currentRemoteService.CancellationSource.Token).ConfigureAwait(false);
if (initializedService.ServiceOpt != null && initializedService.ServiceOpt.Process.IsAlive())
{
......@@ -359,7 +374,10 @@ private async Task<InitializedRemoteService> TryGetOrCreateRemoteServiceAsync(bo
}
}
_errorOutput.WriteLine(FeaturesResources.Unable_to_create_hosting_process);
lock (_errorOutputGuard)
{
_errorOutput.WriteLine(FeaturesResources.Unable_to_create_hosting_process);
}
}
catch (OperationCanceledException)
{
......
......@@ -92,8 +92,8 @@ private void RedirectOutput()
_synchronizedOutput = new SynchronizedStringWriter();
_synchronizedErrorOutput = new SynchronizedStringWriter();
ClearOutput();
_host.Output = _synchronizedOutput;
_host.ErrorOutput = _synchronizedErrorOutput;
_host.SetOutput(_synchronizedOutput);
_host.SetErrorOutput(_synchronizedErrorOutput);
}
private bool LoadReference(string reference)
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册