Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
lwm1986
roslyn
提交
18809c80
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,发现更多精彩内容 >>
提交
18809c80
编写于
3月 13, 2017
作者:
C
CyrusNajmabadi
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Unify code between C# and VB.
上级
414fa9d7
变更
8
隐藏空白更改
内联
并排
Showing
8 changed file
with
233 addition
and
297 deletion
+233
-297
src/Workspaces/CSharp/Portable/Extensions/SyntaxNodeExtensions.cs
...spaces/CSharp/Portable/Extensions/SyntaxNodeExtensions.cs
+18
-154
src/Workspaces/CSharp/Portable/Extensions/SyntaxTriviaExtensions.cs
...aces/CSharp/Portable/Extensions/SyntaxTriviaExtensions.cs
+3
-9
src/Workspaces/CSharp/Portable/LanguageServices/CSharpSyntaxFactsService.cs
...arp/Portable/LanguageServices/CSharpSyntaxFactsService.cs
+14
-5
src/Workspaces/Core/Portable/LanguageServices/SyntaxFactsService/AbstractSyntaxFactsService.cs
...Services/SyntaxFactsService/AbstractSyntaxFactsService.cs
+160
-1
src/Workspaces/VisualBasic/Portable/CodeGeneration/VisualBasicCodeGenerationService.vb
...rtable/CodeGeneration/VisualBasicCodeGenerationService.vb
+3
-2
src/Workspaces/VisualBasic/Portable/Extensions/SyntaxNodeExtensions.vb
...s/VisualBasic/Portable/Extensions/SyntaxNodeExtensions.vb
+10
-120
src/Workspaces/VisualBasic/Portable/LanguageServices/VisualBasicSyntaxFactsService.vb
...ortable/LanguageServices/VisualBasicSyntaxFactsService.vb
+22
-4
src/Workspaces/VisualBasic/Portable/Utilities/ImportsOrganizer.vb
...spaces/VisualBasic/Portable/Utilities/ImportsOrganizer.vb
+3
-2
未找到文件。
src/Workspaces/CSharp/Portable/Extensions/SyntaxNodeExtensions.cs
浏览文件 @
18809c80
...
...
@@ -186,56 +186,30 @@ public static NamespaceDeclarationSyntax GetInnermostNamespaceDeclarationWithUsi
}
}
// Matches the following:
//
// (whitespace* newline)+
private
static
readonly
Matcher
<
SyntaxTrivia
>
s_oneOrMoreBlankLines
;
// Matches the following:
//
// (whitespace* (single-comment|multi-comment) whitespace* newline)+ OneOrMoreBlankLines
private
static
readonly
Matcher
<
SyntaxTrivia
>
s_bannerMatcher
;
// Used to match the following:
//
// <start-of-file> (whitespace* (single-comment|multi-comment) whitespace* newline)+ blankLine*
private
static
readonly
Matcher
<
SyntaxTrivia
>
s_fileBannerMatcher
;
static
SyntaxNodeExtensions
()
{
var
whitespace
=
Matcher
.
Repeat
(
Match
(
SyntaxKind
.
WhitespaceTrivia
,
"\\b"
));
var
endOfLine
=
Match
(
SyntaxKind
.
EndOfLineTrivia
,
"\\n"
);
var
singleBlankLine
=
Matcher
.
Sequence
(
whitespace
,
endOfLine
);
var
shebangComment
=
Match
(
SyntaxKind
.
ShebangDirectiveTrivia
,
"#!"
);
var
singleLineComment
=
Match
(
SyntaxKind
.
SingleLineCommentTrivia
,
"//"
);
var
multiLineComment
=
Match
(
SyntaxKind
.
MultiLineCommentTrivia
,
"/**/"
);
var
anyCommentMatcher
=
Matcher
.
Choice
(
shebangComment
,
singleLineComment
,
multiLineComment
);
var
commentLine
=
Matcher
.
Sequence
(
whitespace
,
anyCommentMatcher
,
whitespace
,
endOfLine
);
s_oneOrMoreBlankLines
=
Matcher
.
OneOrMore
(
singleBlankLine
);
s_bannerMatcher
=
Matcher
.
Sequence
(
Matcher
.
OneOrMore
(
commentLine
),
s_oneOrMoreBlankLines
);
s_fileBannerMatcher
=
Matcher
.
Sequence
(
Matcher
.
OneOrMore
(
commentLine
),
Matcher
.
Repeat
(
singleBlankLine
));
}
private
static
Matcher
<
SyntaxTrivia
>
Match
(
SyntaxKind
kind
,
string
description
)
{
return
Matcher
.
Single
<
SyntaxTrivia
>(
t
=>
t
.
Kind
()
==
kind
,
description
);
}
public
static
IEnumerable
<
SyntaxTrivia
>
GetAllPrecedingTriviaToPreviousToken
(
this
SyntaxNode
node
,
SourceText
sourceText
=
null
,
bool
includePreviousTokenTrailingTriviaOnlyIfOnSameLine
=
false
)
=>
node
.
GetFirstToken
().
GetAllPrecedingTriviaToPreviousToken
(
sourceText
,
includePreviousTokenTrailingTriviaOnlyIfOnSameLine
);
public
static
ImmutableArray
<
SyntaxTrivia
>
GetLeadingBlankLines
<
TSyntaxNode
>(
this
TSyntaxNode
node
)
where
TSyntaxNode
:
SyntaxNode
=>
CSharpSyntaxFactsService
.
Instance
.
GetLeadingBlankLines
(
node
);
public
static
TSyntaxNode
GetNodeWithoutLeadingBlankLines
<
TSyntaxNode
>(
this
TSyntaxNode
node
)
where
TSyntaxNode
:
SyntaxNode
=>
CSharpSyntaxFactsService
.
Instance
.
GetNodeWithoutLeadingBlankLines
(
node
);
public
static
TSyntaxNode
GetNodeWithoutLeadingBlankLines
<
TSyntaxNode
>(
this
TSyntaxNode
node
,
out
ImmutableArray
<
SyntaxTrivia
>
strippedTrivia
)
where
TSyntaxNode
:
SyntaxNode
=>
CSharpSyntaxFactsService
.
Instance
.
GetNodeWithoutLeadingBlankLines
(
node
,
out
strippedTrivia
);
public
static
ImmutableArray
<
SyntaxTrivia
>
GetLeadingBannerAndPreprocessorDirectives
<
TSyntaxNode
>(
this
TSyntaxNode
node
)
where
TSyntaxNode
:
SyntaxNode
=>
CSharpSyntaxFactsService
.
Instance
.
GetLeadingBannerAndPreprocessorDirectives
(
node
);
public
static
TSyntaxNode
GetNodeWithoutLeadingBannerAndPreprocessorDirectives
<
TSyntaxNode
>(
this
TSyntaxNode
node
)
where
TSyntaxNode
:
SyntaxNode
=>
CSharpSyntaxFactsService
.
Instance
.
GetNodeWithoutLeadingBannerAndPreprocessorDirectives
(
node
);
public
static
TSyntaxNode
GetNodeWithoutLeadingBannerAndPreprocessorDirectives
<
TSyntaxNode
>(
this
TSyntaxNode
node
,
out
ImmutableArray
<
SyntaxTrivia
>
strippedTrivia
)
where
TSyntaxNode
:
SyntaxNode
=>
CSharpSyntaxFactsService
.
Instance
.
GetNodeWithoutLeadingBannerAndPreprocessorDirectives
(
node
,
out
strippedTrivia
);
/// <summary>
/// Returns all of the trivia to the left of this token up to the previous token (concatenates
/// the previous token's trailing trivia and this token's leading trivia).
...
...
@@ -559,116 +533,6 @@ public static bool IsAnyLambdaOrAnonymousMethod(this SyntaxNode node)
return
result
;
}
public
static
IEnumerable
<
SyntaxTrivia
>
GetLeadingBlankLines
<
TSyntaxNode
>(
this
TSyntaxNode
node
)
where
TSyntaxNode
:
SyntaxNode
{
node
.
GetNodeWithoutLeadingBlankLines
(
out
var
blankLines
);
return
blankLines
;
}
public
static
TSyntaxNode
GetNodeWithoutLeadingBlankLines
<
TSyntaxNode
>(
this
TSyntaxNode
node
)
where
TSyntaxNode
:
SyntaxNode
{
return
node
.
GetNodeWithoutLeadingBlankLines
(
out
var
blankLines
);
}
public
static
TSyntaxNode
GetNodeWithoutLeadingBlankLines
<
TSyntaxNode
>(
this
TSyntaxNode
node
,
out
IEnumerable
<
SyntaxTrivia
>
strippedTrivia
)
where
TSyntaxNode
:
SyntaxNode
{
var
leadingTriviaToKeep
=
new
List
<
SyntaxTrivia
>(
node
.
GetLeadingTrivia
());
var
index
=
0
;
s_oneOrMoreBlankLines
.
TryMatch
(
leadingTriviaToKeep
,
ref
index
);
strippedTrivia
=
new
List
<
SyntaxTrivia
>(
leadingTriviaToKeep
.
Take
(
index
));
return
node
.
WithLeadingTrivia
(
leadingTriviaToKeep
.
Skip
(
index
));
}
public
static
IEnumerable
<
SyntaxTrivia
>
GetLeadingBannerAndPreprocessorDirectives
<
TSyntaxNode
>(
this
TSyntaxNode
node
)
where
TSyntaxNode
:
SyntaxNode
{
node
.
GetNodeWithoutLeadingBannerAndPreprocessorDirectives
(
out
var
leadingTrivia
);
return
leadingTrivia
;
}
public
static
TSyntaxNode
GetNodeWithoutLeadingBannerAndPreprocessorDirectives
<
TSyntaxNode
>(
this
TSyntaxNode
node
)
where
TSyntaxNode
:
SyntaxNode
{
return
node
.
GetNodeWithoutLeadingBannerAndPreprocessorDirectives
(
out
var
strippedTrivia
);
}
public
static
TSyntaxNode
GetNodeWithoutLeadingBannerAndPreprocessorDirectives
<
TSyntaxNode
>(
this
TSyntaxNode
node
,
out
IEnumerable
<
SyntaxTrivia
>
strippedTrivia
)
where
TSyntaxNode
:
SyntaxNode
{
var
leadingTrivia
=
node
.
GetLeadingTrivia
();
// Rules for stripping trivia:
// 1) If there is a pp directive, then it (and all preceding trivia) *must* be stripped.
// This rule supersedes all other rules.
// 2) If there is a doc comment, it cannot be stripped. Even if there is a doc comment,
// followed by 5 new lines, then the doc comment still must stay with the node. This
// rule does *not* supersede rule 1.
// 3) Single line comments in a group (i.e. with no blank lines between them) belong to
// the node *iff* there is no blank line between it and the following trivia.
List
<
SyntaxTrivia
>
leadingTriviaToStrip
,
leadingTriviaToKeep
;
int
ppIndex
=
-
1
;
for
(
int
i
=
leadingTrivia
.
Count
-
1
;
i
>=
0
;
i
--)
{
if
(
SyntaxFacts
.
IsPreprocessorDirective
(
leadingTrivia
[
i
].
Kind
()))
{
ppIndex
=
i
;
break
;
}
}
if
(
ppIndex
!=
-
1
)
{
// We have a pp directive. it (and all previous trivia) must be stripped.
leadingTriviaToStrip
=
new
List
<
SyntaxTrivia
>(
leadingTrivia
.
Take
(
ppIndex
+
1
));
leadingTriviaToKeep
=
new
List
<
SyntaxTrivia
>(
leadingTrivia
.
Skip
(
ppIndex
+
1
));
}
else
{
leadingTriviaToKeep
=
new
List
<
SyntaxTrivia
>(
leadingTrivia
);
leadingTriviaToStrip
=
new
List
<
SyntaxTrivia
>();
}
// Now, consume as many banners as we can. s_fileBannerMatcher will only be matched at
// the start of the file.
var
index
=
0
;
while
(
s_oneOrMoreBlankLines
.
TryMatch
(
leadingTriviaToKeep
,
ref
index
)
||
s_bannerMatcher
.
TryMatch
(
leadingTriviaToKeep
,
ref
index
)
||
(
node
.
FullSpan
.
Start
==
0
&&
s_fileBannerMatcher
.
TryMatch
(
leadingTriviaToKeep
,
ref
index
)))
{
}
leadingTriviaToStrip
.
AddRange
(
leadingTriviaToKeep
.
Take
(
index
));
strippedTrivia
=
leadingTriviaToStrip
;
return
node
.
WithLeadingTrivia
(
leadingTriviaToKeep
.
Skip
(
index
));
}
public
static
ImmutableArray
<
SyntaxTrivia
>
GetFileBanner
(
this
SyntaxNode
root
)
{
Debug
.
Assert
(
root
.
FullSpan
.
Start
==
0
);
var
leadingTrivia
=
root
.
GetLeadingTrivia
();
var
index
=
0
;
s_fileBannerMatcher
.
TryMatch
(
leadingTrivia
.
ToList
(),
ref
index
);
return
ImmutableArray
.
CreateRange
(
leadingTrivia
.
Take
(
index
));
}
public
static
bool
IsAnyAssignExpression
(
this
SyntaxNode
node
)
{
return
SyntaxFacts
.
IsAssignmentExpression
(
node
.
Kind
());
...
...
src/Workspaces/CSharp/Portable/Extensions/SyntaxTriviaExtensions.cs
浏览文件 @
18809c80
...
...
@@ -45,19 +45,13 @@ public static bool IsRegularOrDocComment(this SyntaxTrivia trivia)
}
public
static
bool
IsSingleLineComment
(
this
SyntaxTrivia
trivia
)
{
return
trivia
.
Kind
()
==
SyntaxKind
.
SingleLineCommentTrivia
;
}
=>
trivia
.
Kind
()
==
SyntaxKind
.
SingleLineCommentTrivia
;
public
static
bool
IsMultiLineComment
(
this
SyntaxTrivia
trivia
)
{
return
trivia
.
Kind
()
==
SyntaxKind
.
MultiLineCommentTrivia
;
}
=>
trivia
.
Kind
()
==
SyntaxKind
.
MultiLineCommentTrivia
;
public
static
bool
IsShebangDirective
(
this
SyntaxTrivia
trivia
)
{
return
trivia
.
Kind
()
==
SyntaxKind
.
ShebangDirectiveTrivia
;
}
=>
trivia
.
Kind
()
==
SyntaxKind
.
ShebangDirectiveTrivia
;
public
static
bool
IsCompleteMultiLineComment
(
this
SyntaxTrivia
trivia
)
{
...
...
src/Workspaces/CSharp/Portable/LanguageServices/CSharpSyntaxFactsService.cs
浏览文件 @
18809c80
...
...
@@ -1832,12 +1832,24 @@ public SyntaxNode GetOperandOfPrefixUnaryExpression(SyntaxNode node)
public
SyntaxNode
GetNextExecutableStatement
(
SyntaxNode
statement
)
=>
((
StatementSyntax
)
statement
).
GetNextStatement
();
public
bool
IsWhitespaceTrivia
(
SyntaxTrivia
trivia
)
public
override
bool
IsWhitespaceTrivia
(
SyntaxTrivia
trivia
)
=>
trivia
.
IsWhitespace
();
public
bool
IsEndOfLineTrivia
(
SyntaxTrivia
trivia
)
public
override
bool
IsEndOfLineTrivia
(
SyntaxTrivia
trivia
)
=>
trivia
.
IsEndOfLine
();
public
override
bool
IsSingleLineCommentTrivia
(
SyntaxTrivia
trivia
)
=>
trivia
.
IsSingleLineComment
();
public
override
bool
IsMultiLineCommentTrivia
(
SyntaxTrivia
trivia
)
=>
trivia
.
IsMultiLineComment
();
public
override
bool
IsShebangDirectiveTrivia
(
SyntaxTrivia
trivia
)
=>
trivia
.
IsShebangDirective
();
public
override
bool
IsPreprocessorDirective
(
SyntaxTrivia
trivia
)
=>
SyntaxFacts
.
IsPreprocessorDirective
(
trivia
.
Kind
());
private
class
AddFirstMissingCloseBaceRewriter
:
CSharpSyntaxRewriter
{
private
readonly
SyntaxNode
_contextNode
;
...
...
@@ -1979,8 +1991,5 @@ public bool IsBetweenTypeMembers(SourceText sourceText, SyntaxNode root, int pos
public
ImmutableArray
<
SyntaxNode
>
GetSelectedMembers
(
SyntaxNode
root
,
TextSpan
textSpan
)
=>
ImmutableArray
<
SyntaxNode
>.
CastUp
(
root
.
GetMembersInSpan
(
textSpan
));
public
ImmutableArray
<
SyntaxTrivia
>
GetFileBanner
(
SyntaxNode
root
)
=>
root
.
GetFileBanner
();
}
}
\ No newline at end of file
src/Workspaces/Core/Portable/LanguageServices/SyntaxFactsService/AbstractSyntaxFactsService.cs
浏览文件 @
18809c80
using
System
;
using
System.Collections.Generic
;
using
System.Collections.Immutable
;
using
System.Diagnostics
;
using
System.Linq
;
using
Microsoft.CodeAnalysis.Shared.Utilities
;
using
Roslyn.Utilities
;
namespace
Microsoft.CodeAnalysis.LanguageServices
...
...
@@ -17,6 +21,53 @@ internal abstract class AbstractSyntaxFactsService
private
readonly
static
ObjectPool
<
Dictionary
<
string
,
string
>>
s_aliasMapPool
=
new
ObjectPool
<
Dictionary
<
string
,
string
>>(()
=>
new
Dictionary
<
string
,
string
>(
StringComparer
.
OrdinalIgnoreCase
));
// Matches the following:
//
// (whitespace* newline)+
private
readonly
Matcher
<
SyntaxTrivia
>
_oneOrMoreBlankLines
;
// Matches the following:
//
// (whitespace* (single-comment|multi-comment) whitespace* newline)+ OneOrMoreBlankLines
private
readonly
Matcher
<
SyntaxTrivia
>
_bannerMatcher
;
// Used to match the following:
//
// <start-of-file> (whitespace* (single-comment|multi-comment) whitespace* newline)+ blankLine*
private
readonly
Matcher
<
SyntaxTrivia
>
_fileBannerMatcher
;
protected
AbstractSyntaxFactsService
()
{
var
whitespace
=
Matcher
.
Repeat
(
Matcher
.
Single
<
SyntaxTrivia
>(
IsWhitespaceTrivia
,
"\\b"
));
var
endOfLine
=
Matcher
.
Single
<
SyntaxTrivia
>(
IsEndOfLineTrivia
,
"\\n"
);
var
singleBlankLine
=
Matcher
.
Sequence
(
whitespace
,
endOfLine
);
var
shebangComment
=
Matcher
.
Single
<
SyntaxTrivia
>(
IsShebangDirectiveTrivia
,
"#!"
);
var
singleLineComment
=
Matcher
.
Single
<
SyntaxTrivia
>(
IsSingleLineCommentTrivia
,
"//"
);
var
multiLineComment
=
Matcher
.
Single
<
SyntaxTrivia
>(
IsMultiLineCommentTrivia
,
"/**/"
);
var
anyCommentMatcher
=
Matcher
.
Choice
(
shebangComment
,
singleLineComment
,
multiLineComment
);
var
commentLine
=
Matcher
.
Sequence
(
whitespace
,
anyCommentMatcher
,
whitespace
,
endOfLine
);
_oneOrMoreBlankLines
=
Matcher
.
OneOrMore
(
singleBlankLine
);
_bannerMatcher
=
Matcher
.
Sequence
(
Matcher
.
OneOrMore
(
commentLine
),
_oneOrMoreBlankLines
);
_fileBannerMatcher
=
Matcher
.
Sequence
(
Matcher
.
OneOrMore
(
commentLine
),
Matcher
.
Repeat
(
singleBlankLine
));
}
public
abstract
bool
IsWhitespaceTrivia
(
SyntaxTrivia
trivia
);
public
abstract
bool
IsEndOfLineTrivia
(
SyntaxTrivia
trivia
);
public
abstract
bool
IsSingleLineCommentTrivia
(
SyntaxTrivia
trivia
);
public
abstract
bool
IsMultiLineCommentTrivia
(
SyntaxTrivia
trivia
);
public
abstract
bool
IsShebangDirectiveTrivia
(
SyntaxTrivia
trivia
);
public
abstract
bool
IsPreprocessorDirective
(
SyntaxTrivia
trivia
);
protected
static
List
<
Dictionary
<
string
,
string
>>
AllocateAliasMapList
()
{
return
s_aliasMapListPool
.
Allocate
();
...
...
@@ -47,5 +98,113 @@ protected static void FreeAliasMap(Dictionary<string, string> aliasMap)
{
return
s_aliasMapPool
.
Allocate
();
}
public
ImmutableArray
<
SyntaxTrivia
>
GetLeadingBlankLines
<
TSyntaxNode
>(
TSyntaxNode
node
)
where
TSyntaxNode
:
SyntaxNode
{
GetNodeWithoutLeadingBlankLines
(
node
,
out
var
blankLines
);
return
blankLines
;
}
public
TSyntaxNode
GetNodeWithoutLeadingBlankLines
<
TSyntaxNode
>(
TSyntaxNode
node
)
where
TSyntaxNode
:
SyntaxNode
{
return
GetNodeWithoutLeadingBlankLines
(
node
,
out
var
blankLines
);
}
public
TSyntaxNode
GetNodeWithoutLeadingBlankLines
<
TSyntaxNode
>(
TSyntaxNode
node
,
out
ImmutableArray
<
SyntaxTrivia
>
strippedTrivia
)
where
TSyntaxNode
:
SyntaxNode
{
var
leadingTriviaToKeep
=
new
List
<
SyntaxTrivia
>(
node
.
GetLeadingTrivia
());
var
index
=
0
;
_fileBannerMatcher
.
TryMatch
(
leadingTriviaToKeep
,
ref
index
);
strippedTrivia
=
leadingTriviaToKeep
.
Take
(
index
).
ToImmutableArray
();
return
node
.
WithLeadingTrivia
(
leadingTriviaToKeep
.
Skip
(
index
));
}
public
ImmutableArray
<
SyntaxTrivia
>
GetLeadingBannerAndPreprocessorDirectives
<
TSyntaxNode
>(
TSyntaxNode
node
)
where
TSyntaxNode
:
SyntaxNode
{
GetNodeWithoutLeadingBannerAndPreprocessorDirectives
(
node
,
out
var
leadingTrivia
);
return
leadingTrivia
;
}
public
TSyntaxNode
GetNodeWithoutLeadingBannerAndPreprocessorDirectives
<
TSyntaxNode
>(
TSyntaxNode
node
)
where
TSyntaxNode
:
SyntaxNode
{
return
GetNodeWithoutLeadingBannerAndPreprocessorDirectives
(
node
,
out
var
strippedTrivia
);
}
public
TSyntaxNode
GetNodeWithoutLeadingBannerAndPreprocessorDirectives
<
TSyntaxNode
>(
TSyntaxNode
node
,
out
ImmutableArray
<
SyntaxTrivia
>
strippedTrivia
)
where
TSyntaxNode
:
SyntaxNode
{
var
leadingTrivia
=
node
.
GetLeadingTrivia
();
// Rules for stripping trivia:
// 1) If there is a pp directive, then it (and all preceding trivia) *must* be stripped.
// This rule supersedes all other rules.
// 2) If there is a doc comment, it cannot be stripped. Even if there is a doc comment,
// followed by 5 new lines, then the doc comment still must stay with the node. This
// rule does *not* supersede rule 1.
// 3) Single line comments in a group (i.e. with no blank lines between them) belong to
// the node *iff* there is no blank line between it and the following trivia.
List
<
SyntaxTrivia
>
leadingTriviaToStrip
,
leadingTriviaToKeep
;
var
ppIndex
=
-
1
;
for
(
var
i
=
leadingTrivia
.
Count
-
1
;
i
>=
0
;
i
--)
{
if
(
this
.
IsPreprocessorDirective
(
leadingTrivia
[
i
]))
{
ppIndex
=
i
;
break
;
}
}
if
(
ppIndex
!=
-
1
)
{
// We have a pp directive. it (and all previous trivia) must be stripped.
leadingTriviaToStrip
=
new
List
<
SyntaxTrivia
>(
leadingTrivia
.
Take
(
ppIndex
+
1
));
leadingTriviaToKeep
=
new
List
<
SyntaxTrivia
>(
leadingTrivia
.
Skip
(
ppIndex
+
1
));
}
else
{
leadingTriviaToKeep
=
new
List
<
SyntaxTrivia
>(
leadingTrivia
);
leadingTriviaToStrip
=
new
List
<
SyntaxTrivia
>();
}
// Now, consume as many banners as we can. s_fileBannerMatcher will only be matched at
// the start of the file.
var
index
=
0
;
while
(
_oneOrMoreBlankLines
.
TryMatch
(
leadingTriviaToKeep
,
ref
index
)
||
_bannerMatcher
.
TryMatch
(
leadingTriviaToKeep
,
ref
index
)
||
(
node
.
FullSpan
.
Start
==
0
&&
_fileBannerMatcher
.
TryMatch
(
leadingTriviaToKeep
,
ref
index
)))
{
}
leadingTriviaToStrip
.
AddRange
(
leadingTriviaToKeep
.
Take
(
index
));
strippedTrivia
=
leadingTriviaToStrip
.
ToImmutableArray
();
return
node
.
WithLeadingTrivia
(
leadingTriviaToKeep
.
Skip
(
index
));
}
public
ImmutableArray
<
SyntaxTrivia
>
GetFileBanner
(
SyntaxNode
root
)
{
Debug
.
Assert
(
root
.
FullSpan
.
Start
==
0
);
var
leadingTrivia
=
root
.
GetLeadingTrivia
();
var
index
=
0
;
_fileBannerMatcher
.
TryMatch
(
leadingTrivia
.
ToList
(),
ref
index
);
return
ImmutableArray
.
CreateRange
(
leadingTrivia
.
Take
(
index
));
}
}
}
}
\ No newline at end of file
src/Workspaces/VisualBasic/Portable/CodeGeneration/VisualBasicCodeGenerationService.vb
浏览文件 @
18809c80
...
...
@@ -483,8 +483,9 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.CodeGeneration
Dim
statementArray
=
statements
.
OfType
(
Of
StatementSyntax
).
ToArray
()
Dim
newBlock
As
SyntaxNode
If
options
.
BeforeThisLocation
IsNot
Nothing
Then
Dim
strippedTrivia
As
IEnumerable
(
Of
SyntaxTrivia
)
=
Nothing
Dim
newStatement
=
oldStatement
.
GetNodeWithoutLeadingBannerAndPreprocessorDirectives
(
strippedTrivia
)
Dim
strippedTrivia
As
ImmutableArray
(
Of
SyntaxTrivia
)
=
Nothing
Dim
newStatement
=
VisualBasicSyntaxFactsService
.
Instance
.
GetNodeWithoutLeadingBannerAndPreprocessorDirectives
(
oldStatement
,
strippedTrivia
)
statementArray
(
0
)
=
statementArray
(
0
).
WithLeadingTrivia
(
strippedTrivia
)
...
...
src/Workspaces/VisualBasic/Portable/Extensions/SyntaxNodeExtensions.vb
浏览文件 @
18809c80
...
...
@@ -188,44 +188,6 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.Extensions
Return
Contract
.
FailWithReturn
(
Of
SyntaxList
(
Of
StatementSyntax
))(
"unknown statements container!"
)
End
Function
' Matches the following:
'
' (whitespace* newline)+
Private
ReadOnly
s_oneOrMoreBlankLines
As
Matcher
(
Of
SyntaxTrivia
)
' Matches the following:
'
' (whitespace* comment whitespace* newline)+ OneOrMoreBlankLines
Private
ReadOnly
s_bannerMatcher
As
Matcher
(
Of
SyntaxTrivia
)
' Used to match the following:
'
' <start-of-file> (whitespace* comment whitespace* newline)+ blankLine*
Private
ReadOnly
s_fileBannerMatcher
As
Matcher
(
Of
SyntaxTrivia
)
Sub
New
()
Dim
whitespace
=
Matcher
.
Repeat
(
Match
(
SyntaxKind
.
WhitespaceTrivia
,
"\\b"
))
Dim
endOfLine
=
Match
(
SyntaxKind
.
EndOfLineTrivia
,
"\\n"
)
Dim
singleBlankLine
=
Matcher
.
Sequence
(
whitespace
,
endOfLine
)
Dim
comment
=
Match
(
SyntaxKind
.
CommentTrivia
,
"'"
)
Dim
commentLine
=
Matcher
.
Sequence
(
whitespace
,
comment
,
whitespace
,
endOfLine
)
s_oneOrMoreBlankLines
=
Matcher
.
OneOrMore
(
singleBlankLine
)
s_bannerMatcher
=
Matcher
.
Sequence
(
Matcher
.
OneOrMore
(
commentLine
),
s_oneOrMoreBlankLines
)
s_fileBannerMatcher
=
Matcher
.
Sequence
(
Matcher
.
OneOrMore
(
commentLine
),
Matcher
.
Repeat
(
singleBlankLine
))
End
Sub
Private
Function
Match
(
kind
As
SyntaxKind
,
description
As
String
)
As
Matcher
(
Of
SyntaxTrivia
)
Return
Matcher
.
Single
(
Of
SyntaxTrivia
)(
Function
(
t
)
t
.
Kind
=
kind
,
description
)
End
Function
<
Extension
()
>
Friend
Function
IsMultiLineLambda
(
node
As
SyntaxNode
)
As
Boolean
Return
SyntaxFacts
.
IsMultiLineLambdaExpression
(
node
.
Kind
())
...
...
@@ -448,106 +410,34 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.Extensions
Return
False
End
Function
<
Extension
()
>
Public
Function
GetLeadingBlankLines
(
Of
TSyntaxNode
As
SyntaxNode
)(
node
As
TSyntaxNode
)
As
IEnumerable
(
Of
SyntaxTrivia
)
Dim
blankLines
As
IEnumerable
(
Of
SyntaxTrivia
)
=
Nothing
node
.
GetNodeWithoutLeadingBlankLines
(
blankLines
)
Return
blankLines
Public
Function
GetLeadingBlankLines
(
Of
TSyntaxNode
As
SyntaxNode
)(
node
As
TSyntaxNode
)
As
ImmutableArray
(
Of
SyntaxTrivia
)
Return
VisualBasicSyntaxFactsService
.
Instance
.
GetLeadingBlankLines
(
node
)
End
Function
<
Extension
()
>
Public
Function
GetNodeWithoutLeadingBlankLines
(
Of
TSyntaxNode
As
SyntaxNode
)(
node
As
TSyntaxNode
)
As
TSyntaxNode
Dim
blankLines
As
IEnumerable
(
Of
SyntaxTrivia
)
=
Nothing
Return
node
.
GetNodeWithoutLeadingBlankLines
(
blankLines
)
Return
VisualBasicSyntaxFactsService
.
Instance
.
GetNodeWithoutLeadingBlankLines
(
node
)
End
Function
<
Extension
()
>
Public
Function
GetNodeWithoutLeadingBlankLines
(
Of
TSyntaxNode
As
SyntaxNode
)(
node
As
TSyntaxNode
,
ByRef
strippedTrivia
As
IEnumerable
(
Of
SyntaxTrivia
))
As
TSyntaxNode
Dim
leadingTriviaToKeep
=
New
List
(
Of
SyntaxTrivia
)(
node
.
GetLeadingTrivia
())
Dim
index
=
0
s_oneOrMoreBlankLines
.
TryMatch
(
leadingTriviaToKeep
,
index
)
strippedTrivia
=
New
List
(
Of
SyntaxTrivia
)(
leadingTriviaToKeep
.
Take
(
index
))
Return
DirectCast
(
node
.
WithLeadingTrivia
(
leadingTriviaToKeep
.
Skip
(
index
)),
TSyntaxNode
)
Public
Function
GetNodeWithoutLeadingBlankLines
(
Of
TSyntaxNode
As
SyntaxNode
)(
node
As
TSyntaxNode
,
ByRef
strippedTrivia
As
ImmutableArray
(
Of
SyntaxTrivia
))
As
TSyntaxNode
Return
VisualBasicSyntaxFactsService
.
Instance
.
GetNodeWithoutLeadingBlankLines
(
node
,
strippedTrivia
)
End
Function
<
Extension
()
>
Public
Function
GetLeadingBannerAndPreprocessorDirectives
(
Of
TSyntaxNode
As
SyntaxNode
)(
node
As
TSyntaxNode
)
As
IEnumerable
(
Of
SyntaxTrivia
)
Dim
leadingTrivia
As
IEnumerable
(
Of
SyntaxTrivia
)
=
Nothing
node
.
GetNodeWithoutLeadingBannerAndPreprocessorDirectives
(
leadingTrivia
)
Return
leadingTrivia
Public
Function
GetLeadingBannerAndPreprocessorDirectives
(
Of
TSyntaxNode
As
SyntaxNode
)(
node
As
TSyntaxNode
)
As
ImmutableArray
(
Of
SyntaxTrivia
)
Return
VisualBasicSyntaxFactsService
.
Instance
.
GetLeadingBannerAndPreprocessorDirectives
(
node
)
End
Function
<
Extension
()
>
Public
Function
GetNodeWithoutLeadingBannerAndPreprocessorDirectives
(
Of
TSyntaxNode
As
SyntaxNode
)(
node
As
TSyntaxNode
)
As
TSyntaxNode
Dim
strippedTrivia
As
IEnumerable
(
Of
SyntaxTrivia
)
=
Nothing
Return
node
.
GetNodeWithoutLeadingBannerAndPreprocessorDirectives
(
strippedTrivia
)
Return
VisualBasicSyntaxFactsService
.
Instance
.
GetNodeWithoutLeadingBannerAndPreprocessorDirectives
(
node
)
End
Function
<
Extension
()
>
Public
Function
GetNodeWithoutLeadingBannerAndPreprocessorDirectives
(
Of
TSyntaxNode
As
SyntaxNode
)(
node
As
TSyntaxNode
,
ByRef
strippedTrivia
As
IEnumerable
(
Of
SyntaxTrivia
))
As
TSyntaxNode
Dim
leadingTrivia
=
node
.
GetLeadingTrivia
()
' Rules for stripping trivia:
' 1) If there is a pp directive, then it (and all preceding trivia) *must* be stripped.
' This rule supersedes all other rules.
' 2) If there is a doc comment, it cannot be stripped. Even if there is a doc comment,
' followed by 5 new lines, then the doc comment still must stay with the node. This
' rule does *not* supersede rule 1.
' 3) Single line comments in a group (i.e. with no blank lines between them) belong to
' the node *iff* there is no blank line between it and the following trivia.
Dim
leadingTriviaToStrip
,
leadingTriviaToKeep
As
List
(
Of
SyntaxTrivia
)
Dim
ppIndex
=
-
1
For
i
=
leadingTrivia
.
Count
-
1
To
0
Step
-
1
If
SyntaxFacts
.
IsPreprocessorDirective
(
leadingTrivia
(
i
).
Kind
)
Then
ppIndex
=
i
Exit
For
End
If
Next
If
ppIndex
<>
-
1
Then
' We have a pp directive. it (and all previous trivia) must be stripped.
leadingTriviaToStrip
=
New
List
(
Of
SyntaxTrivia
)(
leadingTrivia
.
Take
(
ppIndex
+
1
))
leadingTriviaToKeep
=
New
List
(
Of
SyntaxTrivia
)(
leadingTrivia
.
Skip
(
ppIndex
+
1
))
Else
leadingTriviaToKeep
=
New
List
(
Of
SyntaxTrivia
)(
leadingTrivia
)
leadingTriviaToStrip
=
New
List
(
Of
SyntaxTrivia
)()
End
If
' Now, consume as many banners as we can. s_fileBannerMatcher will only be matched at
' the start of the file.
Dim
index
=
0
While
(
s_oneOrMoreBlankLines
.
TryMatch
(
leadingTriviaToKeep
,
index
)
OrElse
s_bannerMatcher
.
TryMatch
(
leadingTriviaToKeep
,
index
)
OrElse
(
node
.
FullSpan
.
Start
=
0
AndAlso
s_fileBannerMatcher
.
TryMatch
(
leadingTriviaToKeep
,
index
)))
End
While
leadingTriviaToStrip
.
AddRange
(
leadingTriviaToKeep
.
Take
(
index
))
strippedTrivia
=
leadingTriviaToStrip
Return
DirectCast
(
node
.
WithLeadingTrivia
(
leadingTriviaToKeep
.
Skip
(
index
)),
TSyntaxNode
)
End
Function
<
Extension
>
Public
Function
GetFileBanner
(
root
As
SyntaxNode
)
As
ImmutableArray
(
Of
SyntaxTrivia
)
Debug
.
Assert
(
root
.
FullSpan
.
Start
=
0
)
Dim
leadingTrivia
=
root
.
GetLeadingTrivia
()
Dim
index
=
0
s_fileBannerMatcher
.
TryMatch
(
leadingTrivia
.
ToList
(),
index
)
Return
ImmutableArray
.
CreateRange
(
leadingTrivia
.
Take
(
index
))
Public
Function
GetNodeWithoutLeadingBannerAndPreprocessorDirectives
(
Of
TSyntaxNode
As
SyntaxNode
)(
node
As
TSyntaxNode
,
ByRef
strippedTrivia
As
ImmutableArray
(
Of
SyntaxTrivia
))
As
TSyntaxNode
Return
VisualBasicSyntaxFactsService
.
Instance
.
GetNodeWithoutLeadingBannerAndPreprocessorDirectives
(
node
,
strippedTrivia
)
End
Function
''' <summary>
...
...
src/Workspaces/VisualBasic/Portable/LanguageServices/VisualBasicSyntaxFactsService.vb
浏览文件 @
18809c80
...
...
@@ -1659,14 +1659,32 @@ Namespace Microsoft.CodeAnalysis.VisualBasic
Return
DirectCast
(
statement
,
StatementSyntax
).
GetNextStatement
()
?
.
FirstAncestorOrSelf
(
Of
ExecutableStatementSyntax
)
End
Function
Public
Function
IsWhitespaceTrivia
(
trivia
As
SyntaxTrivia
)
As
Boolean
Implements
ISyntaxFactsService
.
IsWhitespaceTrivia
Public
Overrides
Function
IsWhitespaceTrivia
(
trivia
As
SyntaxTrivia
)
As
Boolean
Implements
ISyntaxFactsService
.
IsWhitespaceTrivia
Return
trivia
.
IsWhitespace
()
End
Function
Public
Function
IsEndOfLineTrivia
(
trivia
As
SyntaxTrivia
)
As
Boolean
Implements
ISyntaxFactsService
.
IsEndOfLineTrivia
Public
Overrides
Function
IsEndOfLineTrivia
(
trivia
As
SyntaxTrivia
)
As
Boolean
Implements
ISyntaxFactsService
.
IsEndOfLineTrivia
Return
trivia
.
IsEndOfLine
()
End
Function
Public
Overrides
Function
IsSingleLineCommentTrivia
(
trivia
As
SyntaxTrivia
)
As
Boolean
Return
trivia
.
Kind
=
SyntaxKind
.
CommentTrivia
End
Function
Public
Overrides
Function
IsMultiLineCommentTrivia
(
trivia
As
SyntaxTrivia
)
As
Boolean
' VB does not have multi-line comments.
Return
False
End
Function
Public
Overrides
Function
IsShebangDirectiveTrivia
(
trivia
As
SyntaxTrivia
)
As
Boolean
' VB does not have shebang directives.
Return
False
End
Function
Public
Overrides
Function
IsPreprocessorDirective
(
trivia
As
SyntaxTrivia
)
As
Boolean
Return
SyntaxFacts
.
IsPreprocessorDirective
(
trivia
.
Kind
())
End
Function
Public
Function
IsRegularComment
(
trivia
As
SyntaxTrivia
)
As
Boolean
Implements
ISyntaxFactsService
.
IsRegularComment
Return
trivia
.
Kind
=
SyntaxKind
.
CommentTrivia
End
Function
...
...
@@ -1734,8 +1752,8 @@ Namespace Microsoft.CodeAnalysis.VisualBasic
Return
ImmutableArray
(
Of
SyntaxNode
).
CastUp
(
root
.
GetMembersInSpan
(
textSpan
))
End
Function
P
ublic
Function
GetFileBanner
(
root
As
SyntaxNode
)
As
ImmutableArray
(
Of
SyntaxTrivia
)
Implements
ISyntaxFactsService
.
GetFileBanner
Return
root
.
GetFileBanner
(
)
P
rivate
Function
ISyntaxFactsService_
GetFileBanner
(
root
As
SyntaxNode
)
As
ImmutableArray
(
Of
SyntaxTrivia
)
Implements
ISyntaxFactsService
.
GetFileBanner
Return
GetFileBanner
(
root
)
End
Function
End
Class
End
Namespace
\ No newline at end of file
src/Workspaces/VisualBasic/Portable/Utilities/ImportsOrganizer.vb
浏览文件 @
18809c80
...
...
@@ -2,6 +2,7 @@
Imports
System
Imports
System.Collections.Generic
Imports
System.Collections.Immutable
Imports
System.Globalization
Imports
System.Linq
Imports
System.Text
...
...
@@ -16,7 +17,7 @@ Imports Microsoft.CodeAnalysis.VisualBasic.Syntax
Imports
Microsoft.CodeAnalysis.VisualBasic.Utilities
Namespace
Microsoft.CodeAnalysis.VisualBasic.Utilities
Friend
Partial
Class
ImportsOrganizer
Partial
Friend
Class
ImportsOrganizer
Public
Shared
Function
Organize
(
[
imports
]
As
SyntaxList
(
Of
ImportsStatementSyntax
),
placeSystemNamespaceFirst
As
Boolean
)
As
SyntaxList
(
Of
ImportsStatementSyntax
)
If
[
imports
]
.
Count
>
1
Then
...
...
@@ -24,7 +25,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.Utilities
If
Not
[
imports
]
.
SpansPreprocessorDirective
()
Then
' If there is a banner comment that precedes the nodes,
' then remove it and store it for later.
Dim
leadingTrivia
As
I
Enumerable
(
Of
SyntaxTrivia
)
=
Nothing
Dim
leadingTrivia
As
I
mmutableArray
(
Of
SyntaxTrivia
)
=
Nothing
initialList
(
0
)
=
initialList
(
0
).
GetNodeWithoutLeadingBannerAndPreprocessorDirectives
(
leadingTrivia
)
Dim
comparer
=
If
(
placeSystemNamespaceFirst
,
ImportsStatementComparer
.
SystemFirstInstance
,
ImportsStatementComparer
.
NormalInstance
)
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录