Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
lwm1986
roslyn
提交
1235c7ef
R
roslyn
项目概览
lwm1986
/
roslyn
与 Fork 源项目一致
从无法访问的项目Fork
通知
1
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
R
roslyn
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
1235c7ef
编写于
8月 18, 2015
作者:
D
David Poeschl
浏览文件
操作
浏览文件
下载
差异文件
Merge pull request #4313 from dpoeschl/RenameTrackingBufferLeak
Fix ITextBuffer leak after RenameTracking commit
上级
aeb79748
afae76f3
变更
3
隐藏空白更改
内联
并排
Showing
3 changed file
with
78 addition
and
24 deletion
+78
-24
src/EditorFeatures/Core/Implementation/RenameTracking/RenameTrackingTaggerProvider.RenameTrackingCommitter.cs
...g/RenameTrackingTaggerProvider.RenameTrackingCommitter.cs
+19
-8
src/EditorFeatures/Core/Implementation/RenameTracking/RenameTrackingTaggerProvider.StateMachine.cs
...nameTracking/RenameTrackingTaggerProvider.StateMachine.cs
+22
-2
src/EditorFeatures/Core/Implementation/RenameTracking/RenameTrackingTaggerProvider.UndoPrimitive.cs
...ameTracking/RenameTrackingTaggerProvider.UndoPrimitive.cs
+37
-14
未找到文件。
src/EditorFeatures/Core/Implementation/RenameTracking/RenameTrackingTaggerProvider.RenameTrackingCommitter.cs
浏览文件 @
1235c7ef
...
...
@@ -137,7 +137,9 @@ private bool ApplyChangesToWorkspace(CancellationToken cancellationToken)
// When this action is undone (the user has undone twice), restore the state
// machine to so that they can continue their original rename tracking session.
UpdateWorkspaceForResetOfTypedIdentifier
(
workspace
,
renameTrackingSolutionSet
.
OriginalSolution
);
var
trackingSessionId
=
_stateMachine
.
StoreCurrentTrackingSessionAndGenerateId
();
UpdateWorkspaceForResetOfTypedIdentifier
(
workspace
,
renameTrackingSolutionSet
.
OriginalSolution
,
trackingSessionId
);
// Now that the solution is back in its original state, notify third parties about
// the coming rename operation.
...
...
@@ -164,7 +166,15 @@ private bool ApplyChangesToWorkspace(CancellationToken cancellationToken)
}
// Undo/redo on this action must always clear the state machine
UpdateWorkspaceForGlobalIdentifierRename
(
workspace
,
finalSolution
,
workspace
.
CurrentSolution
,
_displayText
,
changedDocuments
,
renameTrackingSolutionSet
.
Symbol
,
newName
);
UpdateWorkspaceForGlobalIdentifierRename
(
workspace
,
finalSolution
,
workspace
.
CurrentSolution
,
_displayText
,
changedDocuments
,
renameTrackingSolutionSet
.
Symbol
,
newName
,
trackingSessionId
);
RenameTrackingDismisser
.
DismissRenameTracking
(
workspace
,
changedDocuments
);
return
true
;
...
...
@@ -209,7 +219,7 @@ private async Task<ISymbol> TryGetSymbolAsync(Solution solutionWithOriginalName,
return
tokenRenameInfo
.
HasSymbols
?
tokenRenameInfo
.
Symbols
.
First
()
:
null
;
}
private
void
UpdateWorkspaceForResetOfTypedIdentifier
(
Workspace
workspace
,
Solution
newSolution
)
private
void
UpdateWorkspaceForResetOfTypedIdentifier
(
Workspace
workspace
,
Solution
newSolution
,
int
trackingSessionId
)
{
AssertIsForeground
();
...
...
@@ -219,7 +229,7 @@ private void UpdateWorkspaceForResetOfTypedIdentifier(Workspace workspace, Solut
var
undoHistory
=
_undoHistoryRegistry
.
RegisterHistory
(
_stateMachine
.
Buffer
);
using
(
var
localUndoTransaction
=
undoHistory
.
CreateTransaction
(
EditorFeaturesResources
.
TextBufferChange
))
{
var
undoPrimitiveBefore
=
new
UndoPrimitive
(
_stateMachine
,
shouldRestoreStateOnUndo
:
true
);
var
undoPrimitiveBefore
=
new
UndoPrimitive
(
_stateMachine
.
Buffer
,
trackingSessionId
,
shouldRestoreStateOnUndo
:
true
);
localUndoTransaction
.
AddUndo
(
undoPrimitiveBefore
);
if
(!
workspace
.
TryApplyChanges
(
newSolution
))
...
...
@@ -228,7 +238,7 @@ private void UpdateWorkspaceForResetOfTypedIdentifier(Workspace workspace, Solut
}
// Never resume tracking session on redo
var
undoPrimitiveAfter
=
new
UndoPrimitive
(
_stateMachine
,
shouldRestoreStateOnUndo
:
false
);
var
undoPrimitiveAfter
=
new
UndoPrimitive
(
_stateMachine
.
Buffer
,
trackingSessionId
,
shouldRestoreStateOnUndo
:
false
);
localUndoTransaction
.
AddUndo
(
undoPrimitiveAfter
);
localUndoTransaction
.
Complete
();
...
...
@@ -242,7 +252,8 @@ private void UpdateWorkspaceForResetOfTypedIdentifier(Workspace workspace, Solut
string
undoName
,
IEnumerable
<
DocumentId
>
changedDocuments
,
ISymbol
symbol
,
string
newName
)
string
newName
,
int
trackingSessionId
)
{
AssertIsForeground
();
...
...
@@ -254,7 +265,7 @@ private void UpdateWorkspaceForResetOfTypedIdentifier(Workspace workspace, Solut
using
(
var
workspaceUndoTransaction
=
workspace
.
OpenGlobalUndoTransaction
(
undoName
))
using
(
var
localUndoTransaction
=
undoHistory
.
CreateTransaction
(
undoName
))
{
var
undoPrimitiveBefore
=
new
UndoPrimitive
(
_stateMachine
,
shouldRestoreStateOnUndo
:
false
);
var
undoPrimitiveBefore
=
new
UndoPrimitive
(
_stateMachine
.
Buffer
,
trackingSessionId
,
shouldRestoreStateOnUndo
:
false
);
localUndoTransaction
.
AddUndo
(
undoPrimitiveBefore
);
if
(!
workspace
.
TryApplyChanges
(
newSolution
))
...
...
@@ -272,7 +283,7 @@ private void UpdateWorkspaceForResetOfTypedIdentifier(Workspace workspace, Solut
}
// Never resume tracking session on redo
var
undoPrimitiveAfter
=
new
UndoPrimitive
(
_stateMachine
,
shouldRestoreStateOnUndo
:
false
);
var
undoPrimitiveAfter
=
new
UndoPrimitive
(
_stateMachine
.
Buffer
,
trackingSessionId
,
shouldRestoreStateOnUndo
:
false
);
localUndoTransaction
.
AddUndo
(
undoPrimitiveAfter
);
localUndoTransaction
.
Complete
();
...
...
src/EditorFeatures/Core/Implementation/RenameTracking/RenameTrackingTaggerProvider.StateMachine.cs
浏览文件 @
1235c7ef
...
...
@@ -33,6 +33,11 @@ private class StateMachine : ForegroundThreadAffinitizedObject
private
readonly
ITextBuffer
_buffer
;
private
readonly
IDiagnosticAnalyzerService
_diagnosticAnalyzerService
;
// Store committed sessions so they can be restored on undo/redo. The undo transactions
// may live beyond the lifetime of the buffer tracked by this StateMachine, so storing
// them here allows them to be correctly cleaned up when the buffer goes away.
private
readonly
IList
<
TrackingSession
>
_committedSessions
=
new
List
<
TrackingSession
>();
private
int
_refCount
;
public
TrackingSession
TrackingSession
{
get
;
private
set
;
}
...
...
@@ -242,6 +247,21 @@ public bool ClearVisibleTrackingSession()
return
false
;
}
internal
int
StoreCurrentTrackingSessionAndGenerateId
()
{
AssertIsForeground
();
var
existingIndex
=
_committedSessions
.
IndexOf
(
TrackingSession
);
if
(
existingIndex
>=
0
)
{
return
existingIndex
;
}
var
index
=
_committedSessions
.
Count
;
_committedSessions
.
Insert
(
index
,
TrackingSession
);
return
index
;
}
public
bool
CanInvokeRename
(
out
TrackingSession
trackingSession
,
bool
isSmartTagCheck
=
false
,
bool
waitForResult
=
false
,
CancellationToken
cancellationToken
=
default
(
CancellationToken
))
{
// This needs to be able to run on a background thread for the diagnostic.
...
...
@@ -300,12 +320,12 @@ internal async Task<IEnumerable<Diagnostic>> GetDiagnostic(SyntaxTree tree, Diag
}
}
public
void
RestoreTrackingSession
(
TrackingSession
trackingSession
)
public
void
RestoreTrackingSession
(
int
trackingSessionId
)
{
AssertIsForeground
();
ClearTrackingSession
();
this
.
TrackingSession
=
trackingSession
;
this
.
TrackingSession
=
_committedSessions
[
trackingSessionId
]
;
TrackingSessionUpdated
();
}
...
...
src/EditorFeatures/Core/Implementation/RenameTracking/RenameTrackingTaggerProvider.UndoPrimitive.cs
浏览文件 @
1235c7ef
// 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
Microsoft.VisualStudio.Text
;
using
Microsoft.VisualStudio.Text.Operations
;
namespace
Microsoft.CodeAnalysis.Editor.Implementation.RenameTracking
...
...
@@ -8,14 +9,19 @@ namespace Microsoft.CodeAnalysis.Editor.Implementation.RenameTracking
internal
sealed
partial
class
RenameTrackingTaggerProvider
{
/// <summary>
/// Clears the state machine on relevant undo/redo actions.
/// Clears or restores the state machine on relevant undo/redo actions.
///
/// These may stay alive on the global undo stack well beyond the lifetime of the
/// <see cref="ITextBuffer"/> on which they were created, so we must avoid strong
/// references to anything that may hold that <see cref="ITextBuffer"/> alive.
/// </summary>
private
class
UndoPrimitive
:
ITextUndoPrimitive
{
private
readonly
StateMachine
_stateMachine
;
private
readonly
TrackingSession
_trackingSession
;
private
ITextUndoTransaction
_parent
;
private
readonly
WeakReference
<
ITextBuffer
>
_weakTextBuffer
;
private
readonly
int
_trackingSessionId
;
private
readonly
bool
_shouldRestoreStateOnUndo
;
private
ITextUndoTransaction
_parent
;
public
ITextUndoTransaction
Parent
{
get
{
return
_parent
;
}
...
...
@@ -32,29 +38,46 @@ public bool CanUndo
get
{
return
true
;
}
}
public
UndoPrimitive
(
StateMachine
stateMachine
,
bool
shouldRestoreStateOnUndo
)
public
UndoPrimitive
(
ITextBuffer
textBuffer
,
int
trackingSessionId
,
bool
shouldRestoreStateOnUndo
)
{
_stateMachine
=
stateMachine
;
_trackingSession
=
shouldRestoreStateOnUndo
?
stateMachine
.
TrackingSession
:
null
;
_weakTextBuffer
=
new
WeakReference
<
ITextBuffer
>(
textBuffer
);
_trackingSessionId
=
trackingSessionId
;
_shouldRestoreStateOnUndo
=
shouldRestoreStateOnUndo
;
}
public
void
Do
()
{
_stateMachine
.
ClearTrackingSession
();
StateMachine
stateMachine
;
if
(
TryGetStateMachine
(
out
stateMachine
))
{
stateMachine
.
ClearTrackingSession
();
}
}
public
void
Undo
()
{
if
(
_trackingSession
!=
null
)
StateMachine
stateMachine
;
if
(
TryGetStateMachine
(
out
stateMachine
))
{
_stateMachine
.
RestoreTrackingSession
(
_trackingSession
);
}
else
{
_stateMachine
.
ClearTrackingSession
();
if
(
_shouldRestoreStateOnUndo
)
{
stateMachine
.
RestoreTrackingSession
(
_trackingSessionId
);
}
else
{
stateMachine
.
ClearTrackingSession
();
}
}
}
private
bool
TryGetStateMachine
(
out
StateMachine
stateMachine
)
{
stateMachine
=
null
;
ITextBuffer
textBuffer
;
return
_weakTextBuffer
.
TryGetTarget
(
out
textBuffer
)
&&
textBuffer
.
Properties
.
TryGetProperty
(
typeof
(
StateMachine
),
out
stateMachine
);
}
public
bool
CanMerge
(
ITextUndoPrimitive
older
)
{
return
false
;
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录