Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
lwm1986
roslyn
提交
768d1b34
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,发现更多精彩内容 >>
提交
768d1b34
编写于
5月 15, 2015
作者:
P
Paul Harrington
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Allocation reductions in formatting.
上级
85e4ddc1
变更
8
隐藏空白更改
内联
并排
Showing
8 changed file
with
74 addition
and
94 deletion
+74
-94
src/Workspaces/Core/Portable/Formatting/Engine/AbstractFormatEngine.cs
...s/Core/Portable/Formatting/Engine/AbstractFormatEngine.cs
+11
-10
src/Workspaces/Core/Portable/Formatting/Engine/AbstractFormattingResult.cs
...re/Portable/Formatting/Engine/AbstractFormattingResult.cs
+12
-6
src/Workspaces/Core/Portable/Formatting/Engine/AbstractTriviaDataFactory.FormattedWhitespace.cs
...g/Engine/AbstractTriviaDataFactory.FormattedWhitespace.cs
+1
-1
src/Workspaces/Core/Portable/Formatting/Engine/TokenStream.Changes.cs
...es/Core/Portable/Formatting/Engine/TokenStream.Changes.cs
+16
-43
src/Workspaces/Core/Portable/Formatting/Engine/TokenStream.cs
...Workspaces/Core/Portable/Formatting/Engine/TokenStream.cs
+14
-26
src/Workspaces/Core/Portable/Formatting/FormattingExtensions.cs
...rkspaces/Core/Portable/Formatting/FormattingExtensions.cs
+17
-5
src/Workspaces/Core/Portable/Formatting/TriviaEngine/AbstractTriviaFormatter.cs
...rtable/Formatting/TriviaEngine/AbstractTriviaFormatter.cs
+2
-2
src/Workspaces/VisualBasic/Portable/Formatting/Engine/Trivia/TriviaDataFactory.LineContinuationTrivia.vb
...Engine/Trivia/TriviaDataFactory.LineContinuationTrivia.vb
+1
-1
未找到文件。
src/Workspaces/Core/Portable/Formatting/Engine/AbstractFormatEngine.cs
浏览文件 @
768d1b34
...
...
@@ -443,18 +443,19 @@ private SyntaxToken FindCorrectBaseTokenOfRelativeIndentBlockOperation(IndentBlo
// always create task 1 more than current processor count
var
partitions
=
partitioner
.
GetPartitions
(
this
.
TaskExecutor
==
TaskExecutor
.
Synchronous
?
1
:
Environment
.
ProcessorCount
+
1
);
var
tasks
=
new
List
<
Task
>(
partitions
.
Select
(
partition
=>
this
.
TaskExecutor
.
StartNew
(
()
=>
var
tasks
=
new
Task
[
partitions
.
Count
];
for
(
int
i
=
0
;
i
<
partitions
.
Count
;
i
++)
{
cancellationToken
.
ThrowIfCancellationRequested
();
partition
.
Do
(
operationPair
=>
ApplySpaceAndWrappingOperationsBody
(
context
,
tokenStream
,
operationPair
,
applier
,
cancellationToken
));
},
cancellationToken
)));
var
partition
=
partitions
[
i
];
tasks
[
i
]
=
this
.
TaskExecutor
.
StartNew
(()
=>
{
cancellationToken
.
ThrowIfCancellationRequested
();
partition
.
Do
(
operationPair
=>
ApplySpaceAndWrappingOperationsBody
(
context
,
tokenStream
,
operationPair
,
applier
,
cancellationToken
));
},
cancellationToken
);
}
Task
.
WaitAll
(
tasks
.
ToArray
()
,
cancellationToken
);
Task
.
WaitAll
(
tasks
,
cancellationToken
);
}
}
...
...
src/Workspaces/Core/Portable/Formatting/Engine/AbstractFormattingResult.cs
浏览文件 @
768d1b34
...
...
@@ -62,15 +62,21 @@ private IList<TextChange> CreateTextChanges(CancellationToken cancellationToken)
using
(
Logger
.
LogBlock
(
FunctionId
.
Formatting_CreateTextChanges
,
cancellationToken
))
{
var
data
=
this
.
TokenStream
.
GetTriviaDataWithTokenPair
(
cancellationToken
);
var
result
=
this
.
TaskExecutor
.
Filter
(
data
,
d
=>
d
.
Item2
.
ContainsChanges
,
d
=>
d
,
cancellationToken
)
.
SelectMany
(
d
=>
CreateTextChange
(
d
.
Item1
.
Item1
,
d
.
Item1
.
Item2
,
d
.
Item2
));
return
result
.
ToList
();
var
filtered
=
this
.
TaskExecutor
.
Filter
(
data
,
d
=>
d
.
Item2
.
ContainsChanges
,
d
=>
d
,
cancellationToken
);
var
result
=
new
List
<
TextChange
>();
foreach
(
var
f
in
filtered
)
{
AddTextChanges
(
result
,
f
.
Item1
.
Item1
,
f
.
Item1
.
Item2
,
f
.
Item2
);
}
return
result
;
}
}
private
IEnumerable
<
TextChange
>
CreateTextChange
(
SyntaxToken
token1
,
SyntaxToken
token2
,
TriviaData
data
)
private
void
AddTextChanges
(
List
<
TextChange
>
list
,
SyntaxToken
token1
,
SyntaxToken
token2
,
TriviaData
data
)
{
var
span
=
TextSpan
.
FromBounds
(
token1
.
RawKind
==
0
?
this
.
TreeInfo
.
StartPosition
:
token1
.
Span
.
End
,
token2
.
RawKind
==
0
?
this
.
TreeInfo
.
EndPosition
:
token2
.
SpanStart
);
var
originalString
=
this
.
TreeInfo
.
GetTextBetween
(
token1
,
token2
);
...
...
@@ -78,7 +84,7 @@ private IEnumerable<TextChange> CreateTextChange(SyntaxToken token1, SyntaxToken
foreach
(
var
change
in
data
.
GetTextChanges
(
span
))
{
var
oldText
=
(
change
.
Span
==
span
)
?
originalString
:
originalString
.
Substring
(
change
.
Span
.
Start
-
span
.
Start
,
change
.
Span
.
Length
);
yield
return
change
.
SimpleDiff
(
oldText
);
list
.
Add
(
change
.
SimpleDiff
(
oldText
)
);
}
}
...
...
src/Workspaces/Core/Portable/Formatting/Engine/AbstractTriviaDataFactory.FormattedWhitespace.cs
浏览文件 @
768d1b34
...
...
@@ -35,7 +35,7 @@ private string CreateString(string newLine)
builder
.
Append
(
newLine
);
}
builder
.
Append
(
this
.
Spaces
.
CreateIndentationString
(
this
.
OptionSet
.
GetOption
(
FormattingOptions
.
UseTabs
,
this
.
Language
),
this
.
OptionSet
.
GetOption
(
FormattingOptions
.
TabSize
,
this
.
Language
)
));
builder
.
Append
IndentationString
(
this
.
Spaces
,
this
.
OptionSet
.
GetOption
(
FormattingOptions
.
UseTabs
,
this
.
Language
),
this
.
OptionSet
.
GetOption
(
FormattingOptions
.
TabSize
,
this
.
Language
));
return
StringBuilderPool
.
ReturnAndFree
(
builder
);
}
...
...
src/Workspaces/Core/Portable/Formatting/Engine/TokenStream.Changes.cs
浏览文件 @
768d1b34
...
...
@@ -9,62 +9,35 @@ namespace Microsoft.CodeAnalysis.Formatting
internal
partial
class
TokenStream
{
/// <summary>
///
t
hread-safe collection that holds onto changes
///
T
hread-safe collection that holds onto changes
/// </summary>
private
class
Changes
private
struct
Changes
{
public
const
int
BeginningOfTreeKey
=
-
1
;
public
const
int
EndOfTreeKey
=
-
2
;
private
readonly
ConcurrentDictionary
<
int
,
TriviaData
>
_map
;
// Created lazily
private
ConcurrentDictionary
<
int
,
TriviaData
>
_map
;
public
Changes
()
{
_map
=
new
ConcurrentDictionary
<
int
,
TriviaData
>();
}
public
bool
Contains
(
int
key
)
{
return
_map
.
ContainsKey
(
key
);
}
public
TriviaData
this
[
int
key
]
{
get
{
return
_map
[
key
];
}
}
public
void
Add
(
int
key
,
TriviaData
triviaInfo
)
{
Contract
.
ThrowIfTrue
(
this
.
Contains
(
key
));
_map
.
TryAdd
(
key
,
triviaInfo
);
}
public
void
Replace
(
int
key
,
TriviaData
triviaInfo
)
{
Contract
.
ThrowIfFalse
(
this
.
Contains
(
key
));
_map
[
key
]
=
triviaInfo
;
}
public
void
Remove
(
int
pairIndex
)
public
bool
TryRemove
(
int
pairIndex
)
{
TriviaData
temp
;
_map
.
TryRemove
(
pairIndex
,
out
temp
)
;
return
_map
?.
TryRemove
(
pairIndex
,
out
temp
)
??
false
;
}
public
void
AddOrReplace
(
int
key
,
TriviaData
triviaInfo
)
{
if
(
this
.
Contains
(
key
))
{
Replace
(
key
,
triviaInfo
);
return
;
}
// PERF: Set the concurrency level to 1 because, while the dictionary has to be thread-safe,
// there is very little contention in formatting. A lower concurrency level reduces object
// allocations which are used internally by ConcurrentDictionary for locking.
var
map
=
LazyInitialization
.
EnsureInitialized
(
ref
_map
,
()
=>
new
ConcurrentDictionary
<
int
,
TriviaData
>(
concurrencyLevel
:
1
,
capacity
:
8
));
map
[
key
]
=
triviaInfo
;
}
Add
(
key
,
triviaInfo
);
public
bool
TryGet
(
int
key
,
out
TriviaData
triviaInfo
)
{
triviaInfo
=
null
;
return
_map
?.
TryGetValue
(
key
,
out
triviaInfo
)
??
false
;
}
}
}
...
...
src/Workspaces/Core/Portable/Formatting/Engine/TokenStream.cs
浏览文件 @
768d1b34
...
...
@@ -39,7 +39,7 @@ internal partial class TokenStream
private
readonly
OptionSet
_optionSet
;
// hold onto information that are made to original trivia info
private
readonly
Changes
_changes
;
private
Changes
_changes
;
// factory that will cache trivia info
private
readonly
AbstractTriviaDataFactory
_factory
;
...
...
@@ -65,7 +65,6 @@ public TokenStream(TreeData treeData, OptionSet optionSet, TextSpan spanToFormat
Contract
.
Requires
(
this
.
TokenCount
>
0
);
// initialize trivia related info
_changes
=
new
Changes
();
_cachedOriginalTriviaInfo
=
new
TriviaData
[
this
.
TokenCount
-
1
];
_tokenToIndexMap
=
new
Dictionary
<
SyntaxToken
,
int
>(
this
.
TokenCount
);
...
...
@@ -268,28 +267,14 @@ public void ApplyChange(int pairIndex, TriviaData data)
// do reference equality check
var
sameAsOriginal
=
GetOriginalTriviaData
(
pairIndex
)
==
data
;
if
(
_changes
.
Contains
(
pairIndex
))
if
(
sameAsOriginal
)
{
if
(
sameAsOriginal
)
{
_changes
.
Remove
(
pairIndex
);
return
;
}
// okay it already exist.
// replace existing one
_changes
.
Replace
(
pairIndex
,
data
);
return
;
_changes
.
TryRemove
(
pairIndex
);
}
// triviaInfo is same as original, nothing to do here.
if
(
sameAsOriginal
)
else
{
return
;
_changes
.
AddOrReplace
(
pairIndex
,
data
)
;
}
_changes
.
Add
(
pairIndex
,
data
);
}
public
int
GetCurrentColumn
(
SyntaxToken
token
)
...
...
@@ -465,9 +450,10 @@ public TriviaData GetTriviaDataAtBeginningOfTree()
{
Contract
.
ThrowIfFalse
(
this
.
FormatBeginningOfTree
);
if
(
_changes
.
Contains
(
Changes
.
BeginningOfTreeKey
))
TriviaData
data
;
if
(
_changes
.
TryGet
(
Changes
.
BeginningOfTreeKey
,
out
data
))
{
return
_changes
[
Changes
.
BeginningOfTreeKey
]
;
return
data
;
}
Contract
.
Requires
(
_treeData
.
IsFirstToken
(
this
.
FirstTokenInStream
.
Token
));
...
...
@@ -478,9 +464,10 @@ public TriviaData GetTriviaDataAtEndOfTree()
{
Contract
.
ThrowIfFalse
(
this
.
FormatEndOfTree
);
if
(
_changes
.
Contains
(
Changes
.
EndOfTreeKey
))
TriviaData
data
;
if
(
_changes
.
TryGet
(
Changes
.
EndOfTreeKey
,
out
data
))
{
return
_changes
[
Changes
.
EndOfTreeKey
]
;
return
data
;
}
Contract
.
Requires
(
_treeData
.
IsLastToken
(
this
.
LastTokenInStream
.
Token
));
...
...
@@ -491,9 +478,10 @@ public TriviaData GetTriviaData(int pairIndex)
{
Contract
.
ThrowIfFalse
(
0
<=
pairIndex
&&
pairIndex
<
this
.
TokenCount
-
1
);
if
(
_changes
.
Contains
(
pairIndex
))
TriviaData
data
;
if
(
_changes
.
TryGet
(
pairIndex
,
out
data
))
{
return
_changes
[
pairIndex
]
;
return
data
;
}
// no change between two tokens, return trivia info from original code
...
...
src/Workspaces/Core/Portable/Formatting/FormattingExtensions.cs
浏览文件 @
768d1b34
...
...
@@ -8,6 +8,7 @@
using
Microsoft.CodeAnalysis.Shared.Extensions
;
using
Microsoft.CodeAnalysis.Text
;
using
Roslyn.Utilities
;
using
System.Text
;
namespace
Microsoft.CodeAnalysis.Formatting
{
...
...
@@ -122,6 +123,20 @@ public static string CreateIndentationString(this int desiredIndentation, bool u
return
new
string
(
'\t'
,
numberOfTabs
)
+
new
string
(
' '
,
numberOfSpaces
);
}
public
static
StringBuilder
AppendIndentationString
(
this
StringBuilder
sb
,
int
desiredIndentation
,
bool
useTab
,
int
tabSize
)
{
int
numberOfTabs
=
0
;
int
numberOfSpaces
=
Math
.
Max
(
0
,
desiredIndentation
);
if
(
useTab
)
{
numberOfTabs
=
desiredIndentation
/
tabSize
;
numberOfSpaces
-=
numberOfTabs
*
tabSize
;
}
return
sb
.
Append
(
'\t'
,
repeatCount
:
numberOfTabs
).
Append
(
' '
,
repeatCount
:
numberOfSpaces
);
}
public
static
void
ProcessTextBetweenTokens
(
this
string
text
,
TreeData
treeInfo
,
...
...
@@ -168,9 +183,8 @@ public static string CreateIndentationString(this int desiredIndentation, bool u
}
var
newIndentation
=
GetNewIndentationForComments
(
triviaText
,
nonWhitespaceCharIndex
,
forceIndentation
,
indentation
,
indentationDelta
,
tabSize
);
var
newIndentationString
=
newIndentation
.
CreateIndentationString
(
useTab
,
tabSize
);
builder
.
Append
(
newIndentationString
);
builder
.
Append
IndentationString
(
newIndentation
,
useTab
,
tabSize
);
if
(!
isEmptyString
)
{
builder
.
Append
(
triviaText
,
nonWhitespaceCharIndex
,
triviaText
.
Length
-
nonWhitespaceCharIndex
);
...
...
@@ -209,9 +223,7 @@ public static string CreateIndentationString(this int desiredIndentation, bool u
if
(
nonWhitespaceCharIndex
>=
0
)
{
var
newIndentation
=
GetNewIndentationForComments
(
line
,
nonWhitespaceCharIndex
,
forceIndentation
,
indentation
,
indentationDelta
,
tabSize
);
var
newIndentationString
=
newIndentation
.
CreateIndentationString
(
useTab
,
tabSize
);
builder
.
Append
(
newIndentationString
);
builder
.
AppendIndentationString
(
newIndentation
,
useTab
,
tabSize
);
builder
.
Append
(
line
,
nonWhitespaceCharIndex
,
line
.
Length
-
nonWhitespaceCharIndex
);
}
...
...
src/Workspaces/Core/Portable/Formatting/TriviaEngine/AbstractTriviaFormatter.cs
浏览文件 @
768d1b34
...
...
@@ -811,12 +811,12 @@ private string GetWhitespaceString(LineColumn lineColumn, LineColumnDelta delta)
// space indicates indentation
if
(
delta
.
Lines
>
0
||
lineColumn
.
Column
==
0
)
{
sb
.
Append
(
delta
.
Spaces
.
CreateIndentationString
(
useTabs
,
tabSize
)
);
sb
.
Append
IndentationString
(
delta
.
Spaces
,
useTabs
,
tabSize
);
return
StringBuilderPool
.
ReturnAndFree
(
sb
);
}
// space indicates space between two noisy trivia or tokens
sb
.
Append
(
GetSpaces
(
delta
.
Spaces
)
);
sb
.
Append
(
' '
,
repeatCount
:
delta
.
Spaces
);
return
StringBuilderPool
.
ReturnAndFree
(
sb
);
}
...
...
src/Workspaces/VisualBasic/Portable/Formatting/Engine/Trivia/TriviaDataFactory.LineContinuationTrivia.vb
浏览文件 @
768d1b34
...
...
@@ -35,7 +35,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.Formatting
builder
.
Append
(
" "
c
)
builder
.
Append
(
SyntaxFacts
.
GetText
(
SyntaxKind
.
LineContinuationTrivia
))
builder
.
Append
(
Me
.
Spaces
.
CreateIndentationString
(
Me
.
OptionSet
.
GetOption
(
FormattingOptions
.
UseTabs
,
LanguageNames
.
VisualBasic
),
Me
.
OptionSet
.
GetOption
(
FormattingOptions
.
TabSize
,
LanguageNames
.
VisualBasic
)
))
builder
.
Append
IndentationString
(
Me
.
Spaces
,
Me
.
OptionSet
.
GetOption
(
FormattingOptions
.
UseTabs
,
LanguageNames
.
VisualBasic
),
Me
.
OptionSet
.
GetOption
(
FormattingOptions
.
TabSize
,
LanguageNames
.
VisualBasic
))
Return
StringBuilderPool
.
ReturnAndFree
(
builder
)
End
Function
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录