提交 463a7164 编写于 作者: J Jason Malinowski

Merge remote-tracking branch 'dotnet/microupdate' into master

static Microsoft.CodeAnalysis.Diagnostics.CompilationWithAnalyzers.GetEffectiveDiagnostics(System.Collections.Immutable.ImmutableArray<Microsoft.CodeAnalysis.Diagnostic> diagnostics, Microsoft.CodeAnalysis.Compilation compilation) -> System.Collections.Generic.IEnumerable<Microsoft.CodeAnalysis.Diagnostic>
Microsoft.CodeAnalysis.PortableExecutableReference.GetMetadata() -> Microsoft.CodeAnalysis.Metadata
Microsoft.CodeAnalysis.ISourceAssemblySymbol
Microsoft.CodeAnalysis.ISourceAssemblySymbol.Compilation.get -> Microsoft.CodeAnalysis.Compilation
Microsoft.CodeAnalysis.ModuleMetadata.GetMetadataReader() -> System.Reflection.Metadata.MetadataReader
Microsoft.CodeAnalysis.Diagnostics.CompilationWithAnalyzers.GetAnalysisResultAsync(System.Collections.Immutable.ImmutableArray<Microsoft.CodeAnalysis.Diagnostics.DiagnosticAnalyzer> analyzers, System.Threading.CancellationToken cancellationToken) -> System.Threading.Tasks.Task<Microsoft.CodeAnalysis.Diagnostics.AnalysisResult>
Microsoft.CodeAnalysis.Diagnostics.CompilationWithAnalyzers.GetAnalysisResultAsync(System.Threading.CancellationToken cancellationToken) -> System.Threading.Tasks.Task<Microsoft.CodeAnalysis.Diagnostics.AnalysisResult>
Microsoft.CodeAnalysis.Diagnostics.AnalysisResult
Microsoft.CodeAnalysis.Diagnostics.AnalysisResult.AnalyzerTelemetryInfo.get -> System.Collections.Immutable.ImmutableDictionary<Microsoft.CodeAnalysis.Diagnostics.DiagnosticAnalyzer, Microsoft.CodeAnalysis.Diagnostics.Telemetry.AnalyzerTelemetryInfo>
Microsoft.CodeAnalysis.Diagnostics.AnalysisResult.Analyzers.get -> System.Collections.Immutable.ImmutableArray<Microsoft.CodeAnalysis.Diagnostics.DiagnosticAnalyzer>
Microsoft.CodeAnalysis.Diagnostics.AnalysisResult.CompilationDiagnostics.get -> System.Collections.Immutable.ImmutableDictionary<Microsoft.CodeAnalysis.Diagnostics.DiagnosticAnalyzer, System.Collections.Immutable.ImmutableArray<Microsoft.CodeAnalysis.Diagnostic>>
Microsoft.CodeAnalysis.Diagnostics.AnalysisResult.GetAllDiagnostics() -> System.Collections.Immutable.ImmutableArray<Microsoft.CodeAnalysis.Diagnostic>
Microsoft.CodeAnalysis.Diagnostics.AnalysisResult.GetAllDiagnostics(Microsoft.CodeAnalysis.Diagnostics.DiagnosticAnalyzer analyzer) -> System.Collections.Immutable.ImmutableArray<Microsoft.CodeAnalysis.Diagnostic>
Microsoft.CodeAnalysis.Diagnostics.AnalysisResult.SemanticDiagnostics.get -> System.Collections.Immutable.ImmutableDictionary<Microsoft.CodeAnalysis.SyntaxTree, System.Collections.Immutable.ImmutableDictionary<Microsoft.CodeAnalysis.Diagnostics.DiagnosticAnalyzer, System.Collections.Immutable.ImmutableArray<Microsoft.CodeAnalysis.Diagnostic>>>
Microsoft.CodeAnalysis.Diagnostics.AnalysisResult.SyntaxDiagnostics.get -> System.Collections.Immutable.ImmutableDictionary<Microsoft.CodeAnalysis.SyntaxTree, System.Collections.Immutable.ImmutableDictionary<Microsoft.CodeAnalysis.Diagnostics.DiagnosticAnalyzer, System.Collections.Immutable.ImmutableArray<Microsoft.CodeAnalysis.Diagnostic>>>
Microsoft.CodeAnalysis.Accessibility
Microsoft.CodeAnalysis.Accessibility.Friend = 4 -> Microsoft.CodeAnalysis.Accessibility
Microsoft.CodeAnalysis.Accessibility.Internal = 4 -> Microsoft.CodeAnalysis.Accessibility
......
Microsoft.CodeAnalysis.Compilation.CreateTupleTypeSymbol(Microsoft.CodeAnalysis.INamedTypeSymbol underlyingType, System.Collections.Immutable.ImmutableArray<string> elementNames = default(System.Collections.Immutable.ImmutableArray<string>)) -> Microsoft.CodeAnalysis.INamedTypeSymbol
Microsoft.CodeAnalysis.Compilation.CreateTupleTypeSymbol(System.Collections.Immutable.ImmutableArray<Microsoft.CodeAnalysis.ITypeSymbol> elementTypes, System.Collections.Immutable.ImmutableArray<string> elementNames = default(System.Collections.Immutable.ImmutableArray<string>)) -> Microsoft.CodeAnalysis.INamedTypeSymbol
Microsoft.CodeAnalysis.Diagnostics.AnalysisContext.RegisterOperationAction(System.Action<Microsoft.CodeAnalysis.Diagnostics.OperationAnalysisContext> action, params Microsoft.CodeAnalysis.OperationKind[] operationKinds) -> void
Microsoft.CodeAnalysis.Diagnostics.AnalysisResult
Microsoft.CodeAnalysis.Diagnostics.AnalysisResult.AnalyzerTelemetryInfo.get -> System.Collections.Immutable.ImmutableDictionary<Microsoft.CodeAnalysis.Diagnostics.DiagnosticAnalyzer, Microsoft.CodeAnalysis.Diagnostics.Telemetry.AnalyzerTelemetryInfo>
Microsoft.CodeAnalysis.Diagnostics.AnalysisResult.Analyzers.get -> System.Collections.Immutable.ImmutableArray<Microsoft.CodeAnalysis.Diagnostics.DiagnosticAnalyzer>
Microsoft.CodeAnalysis.Diagnostics.AnalysisResult.CompilationDiagnostics.get -> System.Collections.Immutable.ImmutableDictionary<Microsoft.CodeAnalysis.Diagnostics.DiagnosticAnalyzer, System.Collections.Immutable.ImmutableArray<Microsoft.CodeAnalysis.Diagnostic>>
Microsoft.CodeAnalysis.Diagnostics.AnalysisResult.GetAllDiagnostics() -> System.Collections.Immutable.ImmutableArray<Microsoft.CodeAnalysis.Diagnostic>
Microsoft.CodeAnalysis.Diagnostics.AnalysisResult.GetAllDiagnostics(Microsoft.CodeAnalysis.Diagnostics.DiagnosticAnalyzer analyzer) -> System.Collections.Immutable.ImmutableArray<Microsoft.CodeAnalysis.Diagnostic>
Microsoft.CodeAnalysis.Diagnostics.AnalysisResult.SemanticDiagnostics.get -> System.Collections.Immutable.ImmutableDictionary<Microsoft.CodeAnalysis.SyntaxTree, System.Collections.Immutable.ImmutableDictionary<Microsoft.CodeAnalysis.Diagnostics.DiagnosticAnalyzer, System.Collections.Immutable.ImmutableArray<Microsoft.CodeAnalysis.Diagnostic>>>
Microsoft.CodeAnalysis.Diagnostics.AnalysisResult.SyntaxDiagnostics.get -> System.Collections.Immutable.ImmutableDictionary<Microsoft.CodeAnalysis.SyntaxTree, System.Collections.Immutable.ImmutableDictionary<Microsoft.CodeAnalysis.Diagnostics.DiagnosticAnalyzer, System.Collections.Immutable.ImmutableArray<Microsoft.CodeAnalysis.Diagnostic>>>
Microsoft.CodeAnalysis.Diagnostics.CompilationStartAnalysisContext.RegisterOperationAction(System.Action<Microsoft.CodeAnalysis.Diagnostics.OperationAnalysisContext> action, params Microsoft.CodeAnalysis.OperationKind[] operationKinds) -> void
Microsoft.CodeAnalysis.Diagnostics.CompilationWithAnalyzers.GetAnalysisResultAsync(System.Collections.Immutable.ImmutableArray<Microsoft.CodeAnalysis.Diagnostics.DiagnosticAnalyzer> analyzers, System.Threading.CancellationToken cancellationToken) -> System.Threading.Tasks.Task<Microsoft.CodeAnalysis.Diagnostics.AnalysisResult>
Microsoft.CodeAnalysis.Diagnostics.CompilationWithAnalyzers.GetAnalysisResultAsync(System.Threading.CancellationToken cancellationToken) -> System.Threading.Tasks.Task<Microsoft.CodeAnalysis.Diagnostics.AnalysisResult>
Microsoft.CodeAnalysis.Diagnostics.OperationAnalysisContext
Microsoft.CodeAnalysis.Diagnostics.OperationAnalysisContext.CancellationToken.get -> System.Threading.CancellationToken
Microsoft.CodeAnalysis.Diagnostics.OperationAnalysisContext.Compilation.get -> Microsoft.CodeAnalysis.Compilation
......@@ -53,11 +43,8 @@ Microsoft.CodeAnalysis.IOperation.Kind.get -> Microsoft.CodeAnalysis.OperationKi
Microsoft.CodeAnalysis.IOperation.Syntax.get -> Microsoft.CodeAnalysis.SyntaxNode
Microsoft.CodeAnalysis.IOperation.Type.get -> Microsoft.CodeAnalysis.ITypeSymbol
Microsoft.CodeAnalysis.IPropertySymbol.ReturnsByRef.get -> bool
Microsoft.CodeAnalysis.ISourceAssemblySymbol
Microsoft.CodeAnalysis.ISourceAssemblySymbol.Compilation.get -> Microsoft.CodeAnalysis.Compilation
Microsoft.CodeAnalysis.ITypeSymbol.IsTupleType.get -> bool
Microsoft.CodeAnalysis.MethodKind.LocalFunction = 17 -> Microsoft.CodeAnalysis.MethodKind
Microsoft.CodeAnalysis.ModuleMetadata.GetMetadataReader() -> System.Reflection.Metadata.MetadataReader
Microsoft.CodeAnalysis.OperationKind
Microsoft.CodeAnalysis.OperationKind.AddressOfExpression = 515 -> Microsoft.CodeAnalysis.OperationKind
Microsoft.CodeAnalysis.OperationKind.Argument = 1031 -> Microsoft.CodeAnalysis.OperationKind
......@@ -135,7 +122,6 @@ Microsoft.CodeAnalysis.OperationKind.VariableDeclarationStatement = 3 -> Microso
Microsoft.CodeAnalysis.OperationKind.WithStatement = 82 -> Microsoft.CodeAnalysis.OperationKind
Microsoft.CodeAnalysis.OperationKind.YieldBreakStatement = 12 -> Microsoft.CodeAnalysis.OperationKind
Microsoft.CodeAnalysis.OperationKind.YieldReturnStatement = 16 -> Microsoft.CodeAnalysis.OperationKind
Microsoft.CodeAnalysis.PortableExecutableReference.GetMetadata() -> Microsoft.CodeAnalysis.Metadata
Microsoft.CodeAnalysis.SemanticModel.GetOperation(Microsoft.CodeAnalysis.SyntaxNode node, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> Microsoft.CodeAnalysis.IOperation
Microsoft.CodeAnalysis.Semantics.ArgumentKind
Microsoft.CodeAnalysis.Semantics.ArgumentKind.DefaultValue = 4 -> Microsoft.CodeAnalysis.Semantics.ArgumentKind
......@@ -748,7 +734,6 @@ override Microsoft.CodeAnalysis.Semantics.OperationWalker.VisitVariableDeclarati
override Microsoft.CodeAnalysis.Semantics.OperationWalker.VisitWhileUntilLoopStatement(Microsoft.CodeAnalysis.Semantics.IWhileUntilLoopStatement operation) -> void
override Microsoft.CodeAnalysis.Semantics.OperationWalker.VisitWithStatement(Microsoft.CodeAnalysis.Semantics.IWithStatement operation) -> void
override Microsoft.CodeAnalysis.Semantics.OperationWalker.VisitYieldBreakStatement(Microsoft.CodeAnalysis.Semantics.IReturnStatement operation) -> void
static Microsoft.CodeAnalysis.Diagnostics.CompilationWithAnalyzers.GetEffectiveDiagnostics(System.Collections.Immutable.ImmutableArray<Microsoft.CodeAnalysis.Diagnostic> diagnostics, Microsoft.CodeAnalysis.Compilation compilation) -> System.Collections.Generic.IEnumerable<Microsoft.CodeAnalysis.Diagnostic>
static Microsoft.CodeAnalysis.Semantics.OperationExtensions.Descendants(this Microsoft.CodeAnalysis.IOperation operation) -> System.Collections.Generic.IEnumerable<Microsoft.CodeAnalysis.IOperation>
static Microsoft.CodeAnalysis.Semantics.OperationExtensions.DescendantsAndSelf(this Microsoft.CodeAnalysis.IOperation operation) -> System.Collections.Generic.IEnumerable<Microsoft.CodeAnalysis.IOperation>
static Microsoft.CodeAnalysis.Semantics.OperationExtensions.GetRootOperation(this Microsoft.CodeAnalysis.ISymbol symbol, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> Microsoft.CodeAnalysis.IOperation
......@@ -923,4 +908,4 @@ virtual Microsoft.CodeAnalysis.Semantics.OperationVisitor<TArgument, TResult>.Vi
virtual Microsoft.CodeAnalysis.Semantics.OperationVisitor<TArgument, TResult>.VisitVariableDeclarationStatement(Microsoft.CodeAnalysis.Semantics.IVariableDeclarationStatement operation, TArgument argument) -> TResult
virtual Microsoft.CodeAnalysis.Semantics.OperationVisitor<TArgument, TResult>.VisitWhileUntilLoopStatement(Microsoft.CodeAnalysis.Semantics.IWhileUntilLoopStatement operation, TArgument argument) -> TResult
virtual Microsoft.CodeAnalysis.Semantics.OperationVisitor<TArgument, TResult>.VisitWithStatement(Microsoft.CodeAnalysis.Semantics.IWithStatement operation, TArgument argument) -> TResult
virtual Microsoft.CodeAnalysis.Semantics.OperationVisitor<TArgument, TResult>.VisitYieldBreakStatement(Microsoft.CodeAnalysis.Semantics.IReturnStatement operation, TArgument argument) -> TResult
\ No newline at end of file
virtual Microsoft.CodeAnalysis.Semantics.OperationVisitor<TArgument, TResult>.VisitYieldBreakStatement(Microsoft.CodeAnalysis.Semantics.IReturnStatement operation, TArgument argument) -> TResult
......@@ -365,10 +365,9 @@ public void TestRemoveProjectWithOpenedDocuments()
workspace.AddTestProject(project1);
workspace.OnDocumentOpened(document.Id, document.GetOpenTextContainer());
Assert.Throws<ArgumentException>(() => workspace.OnProjectRemoved(project1.Id));
workspace.OnDocumentClosed(document.Id);
workspace.OnProjectRemoved(project1.Id);
Assert.False(workspace.IsDocumentOpen(document.Id));
Assert.Empty(workspace.CurrentSolution.Projects);
}
}
......
// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Linq;
using System.Threading;
using Microsoft.CodeAnalysis.Completion;
......@@ -12,8 +13,8 @@
using Microsoft.VisualStudio.Text;
using Microsoft.VisualStudio.Text.Differencing;
using Microsoft.VisualStudio.Text.Operations;
using Microsoft.CodeAnalysis.Text.Shared.Extensions;
using Roslyn.Utilities;
using System.Collections.Immutable;
namespace Microsoft.CodeAnalysis.Editor.Implementation.IntelliSense.Completion
{
......@@ -52,7 +53,7 @@ private void Commit(PresentationItem item, Model model, char? commitChar)
private void Commit(PresentationItem item, Model model, char? commitChar, CancellationToken cancellationToken)
{
var textChanges = ImmutableArray<TextChange>.Empty;
var textChangesInTriggerSnapshot = ImmutableArray<TextChange>.Empty;
// NOTE(cyrusn): It is intentional that we get the undo history for the
// surface buffer and not the subject buffer.
......@@ -75,16 +76,14 @@ private void Commit(PresentationItem item, Model model, char? commitChar, Cancel
if (provider == null)
{
var viewBuffer = this.TextView.TextBuffer;
var commitDocument = this.SubjectBuffer.CurrentSnapshot.AsText().GetDocumentWithFrozenPartialSemanticsAsync(cancellationToken).WaitAndGetResult(cancellationToken);
// adjust commit item span foward to match current document that is passed to GetChangeAsync below
var commitItem = item.Item;
var currentItemSpan = GetCurrentItemSpan(commitItem, model);
commitItem = commitItem.WithSpan(currentItemSpan);
var triggerSnapshotDocument = model.TriggerSnapshot.AsText().GetDocumentWithFrozenPartialSemanticsAsync(cancellationToken).WaitAndGetResult(cancellationToken);
var completionService = CompletionService.GetService(commitDocument);
var commitChange = completionService.GetChangeAsync(commitDocument, commitItem, commitChar, cancellationToken).WaitAndGetResult(cancellationToken);
textChanges = commitChange.TextChanges;
// Get the desired text changes for this item. Note that these changes are
// specified in terms of the trigger snapshot.
var completionService = CompletionService.GetService(triggerSnapshotDocument);
var triggerSnapshotChange = completionService.GetChangeAsync(
triggerSnapshotDocument, item.Item, commitChar, cancellationToken).WaitAndGetResult(cancellationToken);
textChangesInTriggerSnapshot = triggerSnapshotChange.TextChanges;
// Use character based diffing here to avoid overwriting the commit character placed into the editor.
var editOptions = new EditOptions(new StringDifferenceOptions
......@@ -93,23 +92,35 @@ private void Commit(PresentationItem item, Model model, char? commitChar, Cancel
IgnoreTrimWhiteSpace = EditOptions.DefaultMinimalChange.DifferenceOptions.IgnoreTrimWhiteSpace
});
// edit subject buffer (not view) because text changes are in terms of current document.
using (var textEdit = this.SubjectBuffer.CreateEdit(editOptions, reiteratedVersionNumber: null, editTag: null))
var textChangesInCurrentViewSnapshot = new List<TextChange>();
foreach (var triggerSnapshotTextChange in textChangesInTriggerSnapshot)
{
// Try mapping the item span against the trigger snapshot to the ViewBuffer's trigger snapshot.
// Then map that forward to the ViewBuffer's current snapshot.
var originalSpanInView = model.GetViewBufferSpan(triggerSnapshotTextChange.Span).TextSpan.ToSnapshotSpan(model.ViewTriggerSnapshot);
var originalViewSpanTranslatedToCurrentViewSnapshot = originalSpanInView.TranslateTo(TextView.TextBuffer.CurrentSnapshot, SpanTrackingMode.EdgeInclusive);
textChangesInCurrentViewSnapshot.Add(new TextChange(originalViewSpanTranslatedToCurrentViewSnapshot.Span.ToTextSpan(), triggerSnapshotTextChange.NewText));
}
// Note: we currently create the edit on the textview's buffer. This is
// necessary as our own
using (var textEdit = TextView.TextBuffer.CreateEdit(editOptions, reiteratedVersionNumber: null, editTag: null))
{
for (int iChange = 0; iChange < textChanges.Length; iChange++)
for (int iChange = 0; iChange < textChangesInCurrentViewSnapshot.Count; iChange++)
{
var textChange = textChanges[iChange];
var textChangeInView = textChangesInCurrentViewSnapshot[iChange];
var isFirst = iChange == 0;
var isLast = iChange == textChanges.Length - 1;
var isLast = iChange == textChangesInCurrentViewSnapshot.Count - 1;
// add commit char to end of last change if not already included
if (isLast && !commitChange.IncludesCommitCharacter && commitChar.HasValue)
if (isLast && !triggerSnapshotChange.IncludesCommitCharacter && commitChar.HasValue)
{
textChange = new TextChange(textChange.Span, textChange.NewText + commitChar.Value);
textChangeInView = new TextChange(
textChangeInView.Span, textChangeInView.NewText + commitChar.Value);
}
var currentSpan = new SnapshotSpan(this.SubjectBuffer.CurrentSnapshot, new Span(textChange.Span.Start, textChange.Span.Length));
// In order to play nicely with automatic brace completion, we need to
// not touch the opening paren. We'll check our span and textchange
// for ( and adjust them accordingly if we find them.
......@@ -118,13 +129,15 @@ private void Commit(PresentationItem item, Model model, char? commitChar, Cancel
// due to that, existing brace completion engine in editor that should take care of interaction between brace completion
// and intellisense doesn't work for us. so we need this kind of workaround to support it nicely.
bool textChanged;
string newText = textChange.NewText;
string newText = textChangeInView.NewText;
if (isFirst)
{
newText = AdjustFirstText(textChange);
newText = AdjustFirstText(textChangeInView);
}
var currentSpan = new SnapshotSpan(TextView.TextBuffer.CurrentSnapshot,
textChangeInView.Span.ToSpan());
if (isLast)
{
newText = AdjustLastText(newText, commitChar.GetValueOrDefault(), out textChanged);
......@@ -161,9 +174,9 @@ private void Commit(PresentationItem item, Model model, char? commitChar, Cancel
}
// adjust the caret position if requested by completion service
if (commitChange.NewPosition != null)
if (triggerSnapshotChange.NewPosition != null)
{
var target = new SnapshotPoint(this.SubjectBuffer.CurrentSnapshot, commitChange.NewPosition.Value);
var target = new SnapshotPoint(this.SubjectBuffer.CurrentSnapshot, triggerSnapshotChange.NewPosition.Value);
this.TextView.TryMoveCaretToAndEnsureVisible(target);
}
......@@ -211,11 +224,11 @@ private void Commit(PresentationItem item, Model model, char? commitChar, Cancel
// find the appropriate range to format.
changes = formattingService.GetFormattingChangesAsync(document, commitChar.Value, caretPoint.Value.Position, cancellationToken).WaitAndGetResult(cancellationToken);
}
else if (textChanges.Length > 0)
else if (textChangesInTriggerSnapshot.Length > 0)
{
// if this is not a supported trigger character for formatting service (space or tab etc.)
// then format the span of the textchange.
var totalSpan = TextSpan.FromBounds(textChanges.Min(c => c.Span.Start), textChanges.Max(c => c.Span.End));
var totalSpan = TextSpan.FromBounds(textChangesInTriggerSnapshot.Min(c => c.Span.Start), textChangesInTriggerSnapshot.Max(c => c.Span.End));
changes = formattingService.GetFormattingChangesAsync(document, totalSpan, cancellationToken).WaitAndGetResult(cancellationToken);
}
......@@ -232,14 +245,6 @@ private void Commit(PresentationItem item, Model model, char? commitChar, Cancel
this.MakeMostRecentItem(item.Item.DisplayText);
}
private TextSpan GetCurrentItemSpan(CompletionItem item, Model model)
{
var originalSpanInView = model.GetViewBufferSpan(item.Span);
var currentSpanInView = model.GetCurrentSpanInSnapshot(originalSpanInView, this.TextView.TextBuffer.CurrentSnapshot);
var newStart = item.Span.Start + (currentSpanInView.Span.Start - originalSpanInView.TextSpan.Start);
return new TextSpan(newStart, currentSpanInView.Length);
}
private SnapshotSpan AdjustLastSpan(SnapshotSpan currentSpan, char commitChar, bool textChanged)
{
var currentSpanText = currentSpan.GetText();
......@@ -288,14 +293,14 @@ private string AdjustFirstText(TextChange textChange)
private string AdjustLastText(string text, char commitChar, out bool textAdjusted)
{
var finaltText = this.SubjectBuffer.GetOption(InternalFeatureOnOffOptions.AutomaticPairCompletion)
var finalText = this.SubjectBuffer.GetOption(InternalFeatureOnOffOptions.AutomaticPairCompletion)
? text.TrimEnd(commitChar)
: text;
// set whether text has changed or not
textAdjusted = finaltText != text;
textAdjusted = finalText != text;
return finaltText;
return finalText;
}
}
}
......@@ -16,7 +16,7 @@ internal class Model
{
private readonly DisconnectedBufferGraph _disconnectedBufferGraph;
public ITextSnapshot TriggerSnapshot { get { return _disconnectedBufferGraph.SubjectBufferSnapshot; } }
public ITextSnapshot ViewTriggerSnapshot { get { return _disconnectedBufferGraph.ViewSnapshot; } }
public CompletionList OriginalList { get; }
public ImmutableArray<PresentationItem> TotalItems { get; }
public ImmutableArray<PresentationItem> FilteredItems { get; }
......
// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
using System.Collections.Immutable;
using System.Threading;
using System.Threading.Tasks;
......@@ -176,5 +177,10 @@ protected override CompletionItem CreateItem(RecommendedKeyword keyword, TextSpa
glyph: Glyph.Keyword,
shouldFormatOnCommit: keyword.ShouldFormatOnCommit);
}
internal override TextSpan GetCurrentSpan(TextSpan span, SourceText text)
{
return CompletionUtilities.GetCompletionItemSpan(text, span.End);
}
}
}
......@@ -110,8 +110,9 @@ protected virtual CompletionItem CreateItem(RecommendedKeyword keyword, TextSpan
var insertionText = item.DisplayText;
if (ch == ' ')
{
var text = await document.GetTextAsync(cancellationToken).ConfigureAwait(false);
var textTypedSoFar = text.GetSubText(item.Span).ToString();
var currentSnapshot = document.Project.Solution.Workspace.CurrentSolution.GetDocument(document.Id);
var text = await currentSnapshot.GetTextAsync(cancellationToken).ConfigureAwait(false);
var textTypedSoFar = text.GetSubText(GetCurrentSpan(item.Span, text)).ToString() + ch;
if (textTypedSoFar.Length > 0 && insertionText.StartsWith(textTypedSoFar, StringComparison.OrdinalIgnoreCase))
{
......@@ -121,5 +122,7 @@ protected virtual CompletionItem CreateItem(RecommendedKeyword keyword, TextSpan
return new TextChange(item.Span, insertionText);
}
internal abstract TextSpan GetCurrentSpan(TextSpan span, SourceText text);
}
}
......@@ -171,5 +171,9 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.Completion.Providers
}.ToImmutableArray()
End Function
Friend Overrides Function GetCurrentSpan(span As TextSpan, text As SourceText) As TextSpan
Return CompletionUtilities.GetCompletionItemSpan(text, span.End)
End Function
End Class
End Namespace
......@@ -58,6 +58,8 @@ Microsoft.VisualStudio.InteractiveWindow.IInteractiveWindow.Write(string text) -
Microsoft.VisualStudio.InteractiveWindow.IInteractiveWindow.WriteError(string text) -> Microsoft.VisualStudio.Text.Span
Microsoft.VisualStudio.InteractiveWindow.IInteractiveWindow.WriteErrorLine(string text) -> Microsoft.VisualStudio.Text.Span
Microsoft.VisualStudio.InteractiveWindow.IInteractiveWindow.WriteLine(string text) -> Microsoft.VisualStudio.Text.Span
Microsoft.VisualStudio.InteractiveWindow.IInteractiveWindow2
Microsoft.VisualStudio.InteractiveWindow.IInteractiveWindow2.AddToHistory(string input) -> void
Microsoft.VisualStudio.InteractiveWindow.IInteractiveWindowEditorFactoryService
Microsoft.VisualStudio.InteractiveWindow.IInteractiveWindowEditorFactoryService.CreateAndActivateBuffer(Microsoft.VisualStudio.InteractiveWindow.IInteractiveWindow window) -> Microsoft.VisualStudio.Text.ITextBuffer
Microsoft.VisualStudio.InteractiveWindow.IInteractiveWindowEditorFactoryService.CreateTextView(Microsoft.VisualStudio.InteractiveWindow.IInteractiveWindow window, Microsoft.VisualStudio.Text.ITextBuffer buffer, Microsoft.VisualStudio.Text.Editor.ITextViewRoleSet roles) -> Microsoft.VisualStudio.Text.Editor.IWpfTextView
......
Microsoft.VisualStudio.InteractiveWindow.IInteractiveWindow2
Microsoft.VisualStudio.InteractiveWindow.IInteractiveWindow2.AddToHistory(string input) -> void
\ No newline at end of file
......@@ -61,9 +61,17 @@ Microsoft.CodeAnalysis.Scripting.Script.GetCompilation() -> Microsoft.CodeAnalys
Microsoft.CodeAnalysis.Scripting.Script.GlobalsType.get -> System.Type
Microsoft.CodeAnalysis.Scripting.Script.Options.get -> Microsoft.CodeAnalysis.Scripting.ScriptOptions
Microsoft.CodeAnalysis.Scripting.Script.Previous.get -> Microsoft.CodeAnalysis.Scripting.Script
Microsoft.CodeAnalysis.Scripting.Script.RunAsync(object globals = null, System.Func<System.Exception, bool> catchException = null, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Threading.Tasks.Task<Microsoft.CodeAnalysis.Scripting.ScriptState>
Microsoft.CodeAnalysis.Scripting.Script.RunAsync(object globals, System.Threading.CancellationToken cancellationToken) -> System.Threading.Tasks.Task<Microsoft.CodeAnalysis.Scripting.ScriptState>
Microsoft.CodeAnalysis.Scripting.Script.RunFromAsync(Microsoft.CodeAnalysis.Scripting.ScriptState previousState, System.Func<System.Exception, bool> catchException = null, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Threading.Tasks.Task<Microsoft.CodeAnalysis.Scripting.ScriptState>
Microsoft.CodeAnalysis.Scripting.Script.RunFromAsync(Microsoft.CodeAnalysis.Scripting.ScriptState previousState, System.Threading.CancellationToken cancellationToken) -> System.Threading.Tasks.Task<Microsoft.CodeAnalysis.Scripting.ScriptState>
Microsoft.CodeAnalysis.Scripting.Script.WithOptions(Microsoft.CodeAnalysis.Scripting.ScriptOptions options) -> Microsoft.CodeAnalysis.Scripting.Script
Microsoft.CodeAnalysis.Scripting.Script<T>
Microsoft.CodeAnalysis.Scripting.Script<T>.CreateDelegate(System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> Microsoft.CodeAnalysis.Scripting.ScriptRunner<T>
Microsoft.CodeAnalysis.Scripting.Script<T>.RunAsync(object globals = null, System.Func<System.Exception, bool> catchException = null, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Threading.Tasks.Task<Microsoft.CodeAnalysis.Scripting.ScriptState<T>>
Microsoft.CodeAnalysis.Scripting.Script<T>.RunAsync(object globals, System.Threading.CancellationToken cancellationToken) -> System.Threading.Tasks.Task<Microsoft.CodeAnalysis.Scripting.ScriptState<T>>
Microsoft.CodeAnalysis.Scripting.Script<T>.RunFromAsync(Microsoft.CodeAnalysis.Scripting.ScriptState previousState, System.Func<System.Exception, bool> catchException = null, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Threading.Tasks.Task<Microsoft.CodeAnalysis.Scripting.ScriptState<T>>
Microsoft.CodeAnalysis.Scripting.Script<T>.RunFromAsync(Microsoft.CodeAnalysis.Scripting.ScriptState previousState, System.Threading.CancellationToken cancellationToken) -> System.Threading.Tasks.Task<Microsoft.CodeAnalysis.Scripting.ScriptState<T>>
Microsoft.CodeAnalysis.Scripting.Script<T>.WithOptions(Microsoft.CodeAnalysis.Scripting.ScriptOptions options) -> Microsoft.CodeAnalysis.Scripting.Script<T>
Microsoft.CodeAnalysis.Scripting.ScriptMetadataResolver
Microsoft.CodeAnalysis.Scripting.ScriptMetadataResolver.BaseDirectory.get -> string
......@@ -106,6 +114,11 @@ Microsoft.CodeAnalysis.Scripting.ScriptSourceResolver.WithSearchPaths(System.Col
Microsoft.CodeAnalysis.Scripting.ScriptSourceResolver.WithSearchPaths(System.Collections.Immutable.ImmutableArray<string> searchPaths) -> Microsoft.CodeAnalysis.Scripting.ScriptSourceResolver
Microsoft.CodeAnalysis.Scripting.ScriptSourceResolver.WithSearchPaths(params string[] searchPaths) -> Microsoft.CodeAnalysis.Scripting.ScriptSourceResolver
Microsoft.CodeAnalysis.Scripting.ScriptState
Microsoft.CodeAnalysis.Scripting.ScriptState.ContinueWithAsync(string code, Microsoft.CodeAnalysis.Scripting.ScriptOptions options = null, System.Func<System.Exception, bool> catchException = null, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Threading.Tasks.Task<Microsoft.CodeAnalysis.Scripting.ScriptState<object>>
Microsoft.CodeAnalysis.Scripting.ScriptState.ContinueWithAsync(string code, Microsoft.CodeAnalysis.Scripting.ScriptOptions options, System.Threading.CancellationToken cancellationToken) -> System.Threading.Tasks.Task<Microsoft.CodeAnalysis.Scripting.ScriptState<object>>
Microsoft.CodeAnalysis.Scripting.ScriptState.ContinueWithAsync<TResult>(string code, Microsoft.CodeAnalysis.Scripting.ScriptOptions options = null, System.Func<System.Exception, bool> catchException = null, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Threading.Tasks.Task<Microsoft.CodeAnalysis.Scripting.ScriptState<TResult>>
Microsoft.CodeAnalysis.Scripting.ScriptState.ContinueWithAsync<TResult>(string code, Microsoft.CodeAnalysis.Scripting.ScriptOptions options, System.Threading.CancellationToken cancellationToken) -> System.Threading.Tasks.Task<Microsoft.CodeAnalysis.Scripting.ScriptState<TResult>>
Microsoft.CodeAnalysis.Scripting.ScriptState.Exception.get -> System.Exception
Microsoft.CodeAnalysis.Scripting.ScriptState.GetVariable(string name) -> Microsoft.CodeAnalysis.Scripting.ScriptVariable
Microsoft.CodeAnalysis.Scripting.ScriptState.ReturnValue.get -> object
Microsoft.CodeAnalysis.Scripting.ScriptState.Script.get -> Microsoft.CodeAnalysis.Scripting.Script
......
Microsoft.CodeAnalysis.Scripting.Script.RunAsync(object globals = null, System.Func<System.Exception, bool> catchException = null, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Threading.Tasks.Task<Microsoft.CodeAnalysis.Scripting.ScriptState>
Microsoft.CodeAnalysis.Scripting.Script.RunAsync(object globals, System.Threading.CancellationToken cancellationToken) -> System.Threading.Tasks.Task<Microsoft.CodeAnalysis.Scripting.ScriptState>
Microsoft.CodeAnalysis.Scripting.Script.RunFromAsync(Microsoft.CodeAnalysis.Scripting.ScriptState previousState, System.Func<System.Exception, bool> catchException = null, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Threading.Tasks.Task<Microsoft.CodeAnalysis.Scripting.ScriptState>
Microsoft.CodeAnalysis.Scripting.Script.RunFromAsync(Microsoft.CodeAnalysis.Scripting.ScriptState previousState, System.Threading.CancellationToken cancellationToken) -> System.Threading.Tasks.Task<Microsoft.CodeAnalysis.Scripting.ScriptState>
Microsoft.CodeAnalysis.Scripting.Script<T>.RunAsync(object globals = null, System.Func<System.Exception, bool> catchException = null, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Threading.Tasks.Task<Microsoft.CodeAnalysis.Scripting.ScriptState<T>>
Microsoft.CodeAnalysis.Scripting.Script<T>.RunAsync(object globals, System.Threading.CancellationToken cancellationToken) -> System.Threading.Tasks.Task<Microsoft.CodeAnalysis.Scripting.ScriptState<T>>
Microsoft.CodeAnalysis.Scripting.Script<T>.RunFromAsync(Microsoft.CodeAnalysis.Scripting.ScriptState previousState, System.Func<System.Exception, bool> catchException = null, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Threading.Tasks.Task<Microsoft.CodeAnalysis.Scripting.ScriptState<T>>
Microsoft.CodeAnalysis.Scripting.Script<T>.RunFromAsync(Microsoft.CodeAnalysis.Scripting.ScriptState previousState, System.Threading.CancellationToken cancellationToken) -> System.Threading.Tasks.Task<Microsoft.CodeAnalysis.Scripting.ScriptState<T>>
Microsoft.CodeAnalysis.Scripting.ScriptState.ContinueWithAsync(string code, Microsoft.CodeAnalysis.Scripting.ScriptOptions options = null, System.Func<System.Exception, bool> catchException = null, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Threading.Tasks.Task<Microsoft.CodeAnalysis.Scripting.ScriptState<object>>
Microsoft.CodeAnalysis.Scripting.ScriptState.ContinueWithAsync(string code, Microsoft.CodeAnalysis.Scripting.ScriptOptions options, System.Threading.CancellationToken cancellationToken) -> System.Threading.Tasks.Task<Microsoft.CodeAnalysis.Scripting.ScriptState<object>>
Microsoft.CodeAnalysis.Scripting.ScriptState.ContinueWithAsync<TResult>(string code, Microsoft.CodeAnalysis.Scripting.ScriptOptions options = null, System.Func<System.Exception, bool> catchException = null, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Threading.Tasks.Task<Microsoft.CodeAnalysis.Scripting.ScriptState<TResult>>
Microsoft.CodeAnalysis.Scripting.ScriptState.ContinueWithAsync<TResult>(string code, Microsoft.CodeAnalysis.Scripting.ScriptOptions options, System.Threading.CancellationToken cancellationToken) -> System.Threading.Tasks.Task<Microsoft.CodeAnalysis.Scripting.ScriptState<TResult>>
Microsoft.CodeAnalysis.Scripting.ScriptState.Exception.get -> System.Exception
\ No newline at end of file
......@@ -363,6 +363,8 @@ private void DetachFromDocument(uint docCookie, string moniker)
_hostProjects.Remove(hostProject.Id);
_docCookiesToHostProject.Remove(docCookie);
document.Dispose();
return;
}
}
......
......@@ -879,10 +879,11 @@ internal void UpdateDocumentContextIfContainsDocument(IVsHierarchy sharedHierarc
// find that one, we can map back to the open buffer and set its active context to
// the appropriate project.
// Note that if there is a single head project and it's in the process of being unloaded
// there might not be a host project.
var hostProject = LinkedFileUtilities.GetContextHostProject(sharedHierarchy, ProjectTracker);
if (hostProject.Hierarchy == sharedHierarchy)
if (hostProject?.Hierarchy == sharedHierarchy)
{
// How?
return;
}
......
......@@ -2,6 +2,8 @@ Microsoft.VisualStudio.LanguageServices.Progression.GraphNodeCreation
Microsoft.VisualStudio.LanguageServices.RQName
Microsoft.VisualStudio.LanguageServices.VisualStudioWorkspace
Microsoft.VisualStudio.LanguageServices.VisualStudioWorkspace.CreatePortableExecutableReference(string filePath, Microsoft.CodeAnalysis.MetadataReferenceProperties properties) -> Microsoft.CodeAnalysis.PortableExecutableReference
XamlGeneratedNamespace.GeneratedInternalTypeHelper
XamlGeneratedNamespace.GeneratedInternalTypeHelper.GeneratedInternalTypeHelper() -> void
abstract Microsoft.VisualStudio.LanguageServices.VisualStudioWorkspace.DisplayReferencedSymbols(Microsoft.CodeAnalysis.Solution solution, System.Collections.Generic.IEnumerable<Microsoft.CodeAnalysis.FindSymbols.ReferencedSymbol> referencedSymbols) -> void
abstract Microsoft.VisualStudio.LanguageServices.VisualStudioWorkspace.GetFileCodeModel(Microsoft.CodeAnalysis.DocumentId documentId) -> EnvDTE.FileCodeModel
abstract Microsoft.VisualStudio.LanguageServices.VisualStudioWorkspace.GetFilePath(Microsoft.CodeAnalysis.DocumentId documentId) -> string
......
XamlGeneratedNamespace.GeneratedInternalTypeHelper
XamlGeneratedNamespace.GeneratedInternalTypeHelper.GeneratedInternalTypeHelper() -> void
\ No newline at end of file
......@@ -977,6 +977,7 @@ abstract Microsoft.CodeAnalysis.Editing.SyntaxGenerator.MemberAccessExpression(M
abstract Microsoft.CodeAnalysis.Editing.SyntaxGenerator.MethodDeclaration(string name, System.Collections.Generic.IEnumerable<Microsoft.CodeAnalysis.SyntaxNode> parameters = null, System.Collections.Generic.IEnumerable<string> typeParameters = null, Microsoft.CodeAnalysis.SyntaxNode returnType = null, Microsoft.CodeAnalysis.Accessibility accessibility = Microsoft.CodeAnalysis.Accessibility.NotApplicable, Microsoft.CodeAnalysis.Editing.DeclarationModifiers modifiers = default(Microsoft.CodeAnalysis.Editing.DeclarationModifiers), System.Collections.Generic.IEnumerable<Microsoft.CodeAnalysis.SyntaxNode> statements = null) -> Microsoft.CodeAnalysis.SyntaxNode
abstract Microsoft.CodeAnalysis.Editing.SyntaxGenerator.ModuloExpression(Microsoft.CodeAnalysis.SyntaxNode left, Microsoft.CodeAnalysis.SyntaxNode right) -> Microsoft.CodeAnalysis.SyntaxNode
abstract Microsoft.CodeAnalysis.Editing.SyntaxGenerator.MultiplyExpression(Microsoft.CodeAnalysis.SyntaxNode left, Microsoft.CodeAnalysis.SyntaxNode right) -> Microsoft.CodeAnalysis.SyntaxNode
abstract Microsoft.CodeAnalysis.Editing.SyntaxGenerator.NameOfExpression(Microsoft.CodeAnalysis.SyntaxNode expression) -> Microsoft.CodeAnalysis.SyntaxNode
abstract Microsoft.CodeAnalysis.Editing.SyntaxGenerator.NamespaceDeclaration(Microsoft.CodeAnalysis.SyntaxNode name, System.Collections.Generic.IEnumerable<Microsoft.CodeAnalysis.SyntaxNode> declarations) -> Microsoft.CodeAnalysis.SyntaxNode
abstract Microsoft.CodeAnalysis.Editing.SyntaxGenerator.NamespaceImportDeclaration(Microsoft.CodeAnalysis.SyntaxNode name) -> Microsoft.CodeAnalysis.SyntaxNode
abstract Microsoft.CodeAnalysis.Editing.SyntaxGenerator.NegateExpression(Microsoft.CodeAnalysis.SyntaxNode expression) -> Microsoft.CodeAnalysis.SyntaxNode
......@@ -1102,6 +1103,7 @@ override Microsoft.CodeAnalysis.DocumentId.ToString() -> string
override Microsoft.CodeAnalysis.Editing.DeclarationModifiers.Equals(object obj) -> bool
override Microsoft.CodeAnalysis.Editing.DeclarationModifiers.GetHashCode() -> int
override Microsoft.CodeAnalysis.Editing.DeclarationModifiers.ToString() -> string
static Microsoft.CodeAnalysis.Editing.DeclarationModifiers.TryParse(string value, out Microsoft.CodeAnalysis.Editing.DeclarationModifiers modifiers) -> bool
override Microsoft.CodeAnalysis.FindSymbols.ReferenceLocation.Equals(object obj) -> bool
override Microsoft.CodeAnalysis.FindSymbols.ReferenceLocation.GetHashCode() -> int
override Microsoft.CodeAnalysis.Host.Mef.MefHostServices.CreateWorkspaceServices(Microsoft.CodeAnalysis.Workspace workspace) -> Microsoft.CodeAnalysis.Host.HostWorkspaceServices
......
......@@ -21,7 +21,6 @@ Microsoft.CodeAnalysis.Options.OptionSet.OptionSet() -> void
Microsoft.CodeAnalysis.Solution.Options.get -> Microsoft.CodeAnalysis.Options.OptionSet
abstract Microsoft.CodeAnalysis.Editing.SyntaxGenerator.GetSwitchSections(Microsoft.CodeAnalysis.SyntaxNode switchStatement) -> System.Collections.Generic.IReadOnlyList<Microsoft.CodeAnalysis.SyntaxNode>
abstract Microsoft.CodeAnalysis.Editing.SyntaxGenerator.InsertSwitchSections(Microsoft.CodeAnalysis.SyntaxNode switchStatement, int index, System.Collections.Generic.IEnumerable<Microsoft.CodeAnalysis.SyntaxNode> switchSections) -> Microsoft.CodeAnalysis.SyntaxNode
abstract Microsoft.CodeAnalysis.Editing.SyntaxGenerator.NameOfExpression(Microsoft.CodeAnalysis.SyntaxNode expression) -> Microsoft.CodeAnalysis.SyntaxNode
override Microsoft.CodeAnalysis.CodeStyle.NotificationOption.ToString() -> string
override Microsoft.CodeAnalysis.Options.DocumentOptionSet.GetOption(Microsoft.CodeAnalysis.Options.OptionKey optionKey) -> object
override Microsoft.CodeAnalysis.Options.DocumentOptionSet.GetOption<T>(Microsoft.CodeAnalysis.Options.Option<T> option) -> T
......@@ -31,7 +30,6 @@ override Microsoft.CodeAnalysis.Options.DocumentOptionSet.WithChangedOption<T>(M
override Microsoft.CodeAnalysis.Options.DocumentOptionSet.WithChangedOption<T>(Microsoft.CodeAnalysis.Options.PerLanguageOption<T> option, string language, T value) -> Microsoft.CodeAnalysis.Options.OptionSet
static Microsoft.CodeAnalysis.CodeStyle.CodeStyleOption<T>.Default.get -> Microsoft.CodeAnalysis.CodeStyle.CodeStyleOption<T>
static Microsoft.CodeAnalysis.CodeStyle.CodeStyleOption<T>.FromXElement(System.Xml.Linq.XElement element) -> Microsoft.CodeAnalysis.CodeStyle.CodeStyleOption<T>
static Microsoft.CodeAnalysis.Editing.DeclarationModifiers.TryParse(string value, out Microsoft.CodeAnalysis.Editing.DeclarationModifiers modifiers) -> bool
static Microsoft.CodeAnalysis.Simplification.SimplificationOptions.NamingPreferences.get -> Microsoft.CodeAnalysis.Options.PerLanguageOption<string>
static Microsoft.CodeAnalysis.Simplification.SimplificationOptions.QualifyEventAccess.get -> Microsoft.CodeAnalysis.Options.PerLanguageOption<bool>
static Microsoft.CodeAnalysis.Simplification.SimplificationOptions.QualifyFieldAccess.get -> Microsoft.CodeAnalysis.Options.PerLanguageOption<bool>
......
......@@ -425,9 +425,12 @@ protected internal virtual void OnProjectRemoved(ProjectId projectId)
}
}
/// <summary>
/// Currently projects can always be removed, but this method still exists because it's protected and we don't
/// want to break people who may have derived from <see cref="Workspace"/> and either called it, or overridden it.
/// </summary>
protected virtual void CheckProjectCanBeRemoved(ProjectId projectId)
{
CheckProjectDoesNotContainOpenDocuments(projectId);
}
/// <summary>
......
......@@ -75,7 +75,9 @@ private void ClearOpenDocuments(ProjectId projectId)
if (openDocs != null)
{
foreach (var docId in openDocs)
// ClearOpenDocument will remove the document from the original set.
var copyOfOpenDocs = openDocs.ToList();
foreach (var docId in copyOfOpenDocs)
{
this.ClearOpenDocument(docId);
}
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册