Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
lwm1986
roslyn
提交
2212d015
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,发现更多精彩内容 >>
提交
2212d015
编写于
3月 23, 2017
作者:
C
CyrusNajmabadi
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Better codify brace matching invariants.
上级
7cf515cf
变更
3
隐藏空白更改
内联
并排
Showing
3 changed file
with
91 addition
and
47 deletion
+91
-47
src/EditorFeatures/Core/Implementation/BraceMatching/BraceHighlightingViewTaggerProvider.cs
...tion/BraceMatching/BraceHighlightingViewTaggerProvider.cs
+16
-14
src/EditorFeatures/Core/Implementation/BraceMatching/BraceMatchingService.cs
...Core/Implementation/BraceMatching/BraceMatchingService.cs
+3
-3
src/EditorFeatures/Core/Shared/Extensions/IBraceMatchingServiceExtensions.cs
...Core/Shared/Extensions/IBraceMatchingServiceExtensions.cs
+72
-30
未找到文件。
src/EditorFeatures/Core/Implementation/BraceMatching/BraceHighlightingViewTaggerProvider.cs
浏览文件 @
2212d015
...
...
@@ -4,6 +4,7 @@
using
System.Collections.Generic
;
using
System.ComponentModel.Composition
;
using
System.Threading.Tasks
;
using
Microsoft.CodeAnalysis.Editor.Shared.Extensions
;
using
Microsoft.CodeAnalysis.Editor.Shared.Options
;
using
Microsoft.CodeAnalysis.Editor.Shared.Tagging
;
using
Microsoft.CodeAnalysis.Editor.Tagging
;
...
...
@@ -61,25 +62,26 @@ internal async Task ProduceTagsAsync(TaggerContext<BraceHighlightTag> context, D
{
using
(
Logger
.
LogBlock
(
FunctionId
.
Tagger_BraceHighlighting_TagProducer_ProduceTags
,
context
.
CancellationToken
))
{
await
ProduceTagsForBracesAsync
(
context
,
document
,
snapshot
,
position
,
rightBrace
:
false
).
ConfigureAwait
(
false
);
await
ProduceTagsForBracesAsync
(
context
,
document
,
snapshot
,
position
-
1
,
rightBrace
:
true
).
ConfigureAwait
(
false
);
if
(
position
>=
0
&&
position
<=
snapshot
.
Length
)
{
var
(
bracesLeftOfPosition
,
bracesRightOfPosition
)
=
await
_braceMatcherService
.
GetAllMatchingBracesAsync
(
document
,
position
,
context
.
CancellationToken
).
ConfigureAwait
(
false
);
AddBraces
(
context
,
snapshot
,
bracesLeftOfPosition
);
AddBraces
(
context
,
snapshot
,
bracesRightOfPosition
);
}
}
}
private
async
Task
ProduceTagsForBracesAsync
(
TaggerContext
<
BraceHighlightTag
>
context
,
Document
document
,
ITextSnapshot
snapshot
,
int
position
,
bool
rightBrace
)
private
void
AddBraces
(
TaggerContext
<
BraceHighlightTag
>
context
,
ITextSnapshot
snapshot
,
BraceMatchingResult
?
braces
)
{
if
(
position
>=
0
&&
position
<=
snapshot
.
Length
)
if
(
braces
.
HasValue
)
{
var
braces
=
await
_braceMatcherService
.
GetMatchingBracesAsync
(
document
,
position
,
context
.
CancellationToken
).
ConfigureAwait
(
false
);
if
(
braces
.
HasValue
)
{
if
((!
rightBrace
&&
braces
.
Value
.
LeftSpan
.
Start
==
position
)
||
(
rightBrace
&&
braces
.
Value
.
RightSpan
.
Start
==
position
))
{
context
.
AddTag
(
snapshot
.
GetTagSpan
(
braces
.
Value
.
LeftSpan
.
ToSpan
(),
BraceHighlightTag
.
StartTag
));
context
.
AddTag
(
snapshot
.
GetTagSpan
(
braces
.
Value
.
RightSpan
.
ToSpan
(),
BraceHighlightTag
.
EndTag
));
}
}
context
.
AddTag
(
snapshot
.
GetTagSpan
(
braces
.
Value
.
LeftSpan
.
ToSpan
(),
BraceHighlightTag
.
StartTag
));
context
.
AddTag
(
snapshot
.
GetTagSpan
(
braces
.
Value
.
RightSpan
.
ToSpan
(),
BraceHighlightTag
.
EndTag
));
}
}
}
...
...
src/EditorFeatures/Core/Implementation/BraceMatching/BraceMatchingService.cs
浏览文件 @
2212d015
...
...
@@ -2,6 +2,7 @@
using
System
;
using
System.Collections.Generic
;
using
System.Collections.Immutable
;
using
System.ComponentModel.Composition
;
using
System.Linq
;
using
System.Threading
;
...
...
@@ -13,14 +14,13 @@ namespace Microsoft.CodeAnalysis.Editor.Implementation.BraceMatching
[
Export
(
typeof
(
IBraceMatchingService
))]
internal
class
BraceMatchingService
:
IBraceMatchingService
{
private
readonly
List
<
Lazy
<
IBraceMatcher
,
LanguageMetadata
>>
_braceMatchers
;
private
readonly
ImmutableArray
<
Lazy
<
IBraceMatcher
,
LanguageMetadata
>>
_braceMatchers
;
[
ImportingConstructor
]
public
BraceMatchingService
(
[
ImportMany
]
IEnumerable
<
Lazy
<
IBraceMatcher
,
LanguageMetadata
>>
braceMatchers
)
{
////braceMatchers.RealizeImports();
_braceMatchers
=
braceMatchers
.
ToList
();
_braceMatchers
=
braceMatchers
.
ToImmutableArray
();
}
public
async
Task
<
BraceMatchingResult
?>
GetMatchingBracesAsync
(
Document
document
,
int
position
,
CancellationToken
cancellationToken
)
...
...
src/EditorFeatures/Core/Shared/Extensions/IBraceMatchingServiceExtensions.cs
浏览文件 @
2212d015
...
...
@@ -8,50 +8,92 @@ namespace Microsoft.CodeAnalysis.Editor.Shared.Extensions
{
internal
static
class
IBraceMatchingServiceExtensions
{
public
static
async
Task
<
TextSpan
?>
FindMatchingSpanAsync
(
/// <summary>
/// Given code like ()^() (where ^ is the caret position), returns the two pairs of
/// matching braces on the left and the right of the position. Note: a brace matching
/// pair is only returned if the position is on the left-side of hte start brace, or the
/// right side of end brace. So, for example, if you have (^()), then only the inner
/// braces are returned as the position is not on the right-side of the outer braces.
///
/// This function also works for multi-character braces i.e. ([ ]) In this case,
/// the rule is that the position has to be on the left side of the start brace, or
/// inside the start brace (but not at the end). So, ^([ ]) will return this
/// as a brace match, as will (^[ ]). But ([^ ]) will not.
///
/// The same goes for the braces on the the left of the caret. i.e.: ([ ])^
/// will return the braces on the left, as will ([ ]^). But ([ ^]) will not.
/// </summary>
public
static
async
Task
<(
BraceMatchingResult
?
leftOfPosition
,
BraceMatchingResult
?
rightOfPosition
)>
GetAllMatchingBracesAsync
(
this
IBraceMatchingService
service
,
Document
document
,
int
position
,
CancellationToken
cancellationToken
)
{
// These are the matching spans when checking the token to the right of the position.
var
braces1
=
await
service
.
GetMatchingBracesAsync
(
document
,
position
,
cancellationToken
).
ConfigureAwait
(
false
);
// These are the matching spans when checking the token to the left of the position.
BraceMatchingResult
?
braces2
=
null
;
var
rightOfPosition
=
await
service
.
GetMatchingBracesAsync
(
document
,
position
,
cancellationToken
).
ConfigureAwait
(
false
);
// Ensure caret is valid at left of position.
if
(
position
>
0
)
{
braces2
=
await
service
.
GetMatchingBracesAsync
(
document
,
position
-
1
,
cancellationToken
).
ConfigureAwait
(
false
);
}
// Favor matches where the position is on the outside boundary of the braces. i.e. if we
// have: {^()}
// The braces to the right of the position should only be added if the position is
// actually within the span of the start brace. Note that this is what we want for
// single character braces as well as multi char braces. i.e. if the user has:
//
// then this would return the () not the {}
if
(
braces1
.
HasValue
&&
position
>=
braces1
.
Value
.
LeftSpan
.
Start
&&
position
<
braces1
.
Value
.
LeftSpan
.
End
)
{
// ^{ } -- return right span
return
braces1
.
Value
.
RightSpan
;
}
else
if
(
braces2
.
HasValue
&&
position
>
braces2
.
Value
.
RightSpan
.
Start
&&
position
<=
braces2
.
Value
.
RightSpan
.
End
)
// ^{ } // then { and } are matching braces.
// {^ } // then { and } are not matching braces.
//
// ^<@ @> // then <@ and @> are matching braces.
// <^@ @> // then <@ and @> are matching braces.
// <@^ @> // then <@ and @> are not matching braces.
if
(
rightOfPosition
.
HasValue
&&
!
rightOfPosition
.
Value
.
LeftSpan
.
Contains
(
position
))
{
//
{ }^ -- return left span
r
eturn
braces2
.
Value
.
LeftSpan
;
//
Not a valid match.
r
ightOfPosition
=
null
;
}
else
if
(
braces2
.
HasValue
&&
position
>
braces2
.
Value
.
LeftSpan
.
Start
&&
position
<=
braces2
.
Value
.
LeftSpan
.
End
)
if
(
position
==
0
)
{
//
{^ } -- return right span
return
braces2
.
Value
.
RightSpan
;
//
We're at the start of the document, can't find braces to the left of the position.
return
(
leftOfPosition
:
null
,
rightOfPosition
)
;
}
else
if
(
braces1
.
HasValue
&&
position
>=
braces1
.
Value
.
RightSpan
.
Start
&&
position
<
braces1
.
Value
.
RightSpan
.
End
)
// See if we're touching the end of some construct. i.e.:
//
// { }^
// <@ @>^
// <@ @^>
//
// But not
//
// { ^}
// <@ ^@>
var
leftOfPosition
=
await
service
.
GetMatchingBracesAsync
(
document
,
position
-
1
,
cancellationToken
).
ConfigureAwait
(
false
);
if
(
leftOfPosition
.
HasValue
&&
position
<=
leftOfPosition
.
Value
.
RightSpan
.
End
&&
position
>
leftOfPosition
.
Value
.
RightSpan
.
Start
)
{
//
{ ^} -- return left span
return
braces1
.
Value
.
LeftSpan
;
//
Found a valid pair on the left of us.
return
(
leftOfPosition
,
rightOfPosition
)
;
}
// No valid pair of braces on the left of us.
return
(
leftOfPosition
:
null
,
rightOfPosition
);
}
public
static
async
Task
<
TextSpan
?>
FindMatchingSpanAsync
(
this
IBraceMatchingService
service
,
Document
document
,
int
position
,
CancellationToken
cancellationToken
)
{
var
(
bracesLeftOfPosition
,
bracesRightOfPosition
)
=
await
service
.
GetAllMatchingBracesAsync
(
document
,
position
,
cancellationToken
).
ConfigureAwait
(
false
);
return
null
;
// Favor matches where the position is on the outside boundary of the braces. i.e. if we
// have: {}^()
//
// then this would return the () not the {}
return
bracesRightOfPosition
?.
RightSpan
??
bracesLeftOfPosition
?.
LeftSpan
;
}
}
}
}
\ No newline at end of file
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录