Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
lwm1986
roslyn
提交
1ef362f0
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,发现更多精彩内容 >>
提交
1ef362f0
编写于
4月 25, 2020
作者:
A
Alireza Habibi
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Simplify code
上级
53d22f27
变更
4
隐藏空白更改
内联
并排
Showing
4 changed file
with
45 addition
and
99 deletion
+45
-99
src/Features/CSharp/Portable/UsePatternCombinators/AnalyzedPattern.cs
.../CSharp/Portable/UsePatternCombinators/AnalyzedPattern.cs
+24
-29
src/Features/CSharp/Portable/UsePatternCombinators/CSharpUsePatternCombinatorsAnalyzer.cs
...PatternCombinators/CSharpUsePatternCombinatorsAnalyzer.cs
+16
-65
src/Features/CSharp/Portable/UsePatternCombinators/CSharpUsePatternCombinatorsCodeFixProvider.cs
...Combinators/CSharpUsePatternCombinatorsCodeFixProvider.cs
+3
-4
src/Features/CSharp/Portable/UsePatternCombinators/CSharpUsePatternCombinatorsDiagnosticAnalyzer.cs
...binators/CSharpUsePatternCombinatorsDiagnosticAnalyzer.cs
+2
-1
未找到文件。
src/Features/CSharp/Portable/UsePatternCombinators/AnalyzedPattern.cs
浏览文件 @
1ef362f0
...
...
@@ -15,63 +15,53 @@ namespace Microsoft.CodeAnalysis.CSharp.UsePatternCombinators
/// </summary>
internal
abstract
class
AnalyzedPattern
{
private
AnalyzedPattern
()
{
}
/// <summary>
/// Base class for patterns that target a specific expression, i.e. non-combinators
/// </summary>
internal
abstract
class
Test
:
AnalyzedPattern
{
public
readonly
IOperation
TargetOperation
;
public
readonly
ExpressionSyntax
TargetExpression
;
protected
Test
(
IOperation
targetOperation
)
=>
TargetOperation
=
targetOperation
;
}
private
AnalyzedPattern
(
ExpressionSyntax
target
)
=>
TargetExpression
=
target
;
/// <summary>
/// Represents a type-pattern, constructed from is-expression
/// </summary>
internal
sealed
class
Type
:
Test
internal
sealed
class
Type
:
AnalyzedPattern
{
public
readonly
TypeSyntax
TypeSyntax
;
public
Type
(
TypeSyntax
expression
,
IOperation
target
)
:
base
(
target
)
public
Type
(
TypeSyntax
expression
,
ExpressionSyntax
target
)
:
base
(
target
)
=>
TypeSyntax
=
expression
;
}
/// <summary>
/// Represents a source-pattern, constructed from C# patterns
/// </summary>
internal
sealed
class
Source
:
Test
internal
sealed
class
Source
:
AnalyzedPattern
{
public
readonly
PatternSyntax
PatternSyntax
;
public
Source
(
PatternSyntax
patternSyntax
,
IOperation
target
)
:
base
(
target
)
public
Source
(
PatternSyntax
patternSyntax
,
ExpressionSyntax
target
)
:
base
(
target
)
=>
PatternSyntax
=
patternSyntax
;
}
/// <summary>
/// Represents a constant-pattern, constructed from an equality check
/// </summary>
internal
sealed
class
Constant
:
Test
internal
sealed
class
Constant
:
AnalyzedPattern
{
public
readonly
ExpressionSyntax
ExpressionSyntax
;
public
Constant
(
ExpressionSyntax
expression
,
IOperation
target
)
:
base
(
target
)
public
Constant
(
ExpressionSyntax
expression
,
ExpressionSyntax
target
)
:
base
(
target
)
=>
ExpressionSyntax
=
expression
;
}
/// <summary>
/// Represents a relational-pattern, constructed from relational operators
/// </summary>
internal
sealed
class
Relational
:
Test
internal
sealed
class
Relational
:
AnalyzedPattern
{
public
readonly
BinaryOperatorKind
OperatorKind
;
public
readonly
ExpressionSyntax
Value
;
public
Relational
(
BinaryOperatorKind
operatorKind
,
ExpressionSyntax
value
,
IOperation
target
)
:
base
(
target
)
public
Relational
(
BinaryOperatorKind
operatorKind
,
ExpressionSyntax
value
,
ExpressionSyntax
target
)
:
base
(
target
)
{
OperatorKind
=
operatorKind
;
Value
=
value
;
...
...
@@ -88,7 +78,7 @@ internal sealed class Binary : AnalyzedPattern
public
readonly
bool
IsDisjunctive
;
public
readonly
SyntaxToken
Token
;
private
Binary
(
AnalyzedPattern
leftPattern
,
AnalyzedPattern
rightPattern
,
bool
isDisjunctive
,
SyntaxToken
token
)
private
Binary
(
AnalyzedPattern
leftPattern
,
AnalyzedPattern
rightPattern
,
bool
isDisjunctive
,
SyntaxToken
token
,
ExpressionSyntax
target
)
:
base
(
target
)
{
Left
=
leftPattern
;
Right
=
rightPattern
;
...
...
@@ -96,11 +86,15 @@ private Binary(AnalyzedPattern leftPattern, AnalyzedPattern rightPattern, bool i
Token
=
token
;
}
public
static
AnalyzedPattern
Create
(
AnalyzedPattern
leftPattern
,
AnalyzedPattern
rightPattern
,
bool
isDisjunctive
,
SyntaxToken
token
)
public
static
AnalyzedPattern
?
Create
(
AnalyzedPattern
leftPattern
,
AnalyzedPattern
rightPattern
,
bool
isDisjunctive
,
SyntaxToken
token
)
{
var
target
=
leftPattern
.
TargetExpression
;
if
(!
SyntaxFactory
.
AreEquivalent
(
target
,
rightPattern
.
TargetExpression
))
return
null
;
return
!
isDisjunctive
&&
(
leftPattern
,
rightPattern
)
is
(
Not
left
,
Not
right
)
?
Not
.
Create
(
new
Binary
(
left
.
Pattern
,
right
.
Pattern
,
isDisjunctive
:
true
,
token
))
:
new
Binary
(
leftPattern
,
rightPattern
,
isDisjunctive
,
token
);
?
Not
.
Create
(
new
Binary
(
left
.
Pattern
,
right
.
Pattern
,
isDisjunctive
:
true
,
token
,
target
))
:
new
Binary
(
leftPattern
,
rightPattern
,
isDisjunctive
,
token
,
target
);
}
}
...
...
@@ -111,7 +105,7 @@ internal sealed class Not : AnalyzedPattern
{
public
readonly
AnalyzedPattern
Pattern
;
private
Not
(
AnalyzedPattern
pattern
)
private
Not
(
AnalyzedPattern
pattern
,
ExpressionSyntax
target
)
:
base
(
target
)
=>
Pattern
=
pattern
;
private
static
BinaryOperatorKind
Negate
(
BinaryOperatorKind
kind
)
...
...
@@ -124,12 +118,13 @@ private static BinaryOperatorKind Negate(BinaryOperatorKind kind)
var
v
=>
throw
ExceptionUtilities
.
UnexpectedValue
(
v
)
};
public
static
AnalyzedPattern
Create
(
AnalyzedPattern
pattern
)
public
static
AnalyzedPattern
?
Create
(
AnalyzedPattern
?
pattern
)
=>
pattern
switch
{
null
=>
null
,
Not
p
=>
p
.
Pattern
,
Relational
p
=>
new
Relational
(
Negate
(
p
.
OperatorKind
),
p
.
Value
,
p
.
Target
Operat
ion
),
_
=>
new
Not
(
pattern
)
Relational
p
=>
new
Relational
(
Negate
(
p
.
OperatorKind
),
p
.
Value
,
p
.
Target
Express
ion
),
_
=>
new
Not
(
pattern
,
pattern
.
TargetExpression
)
};
}
}
...
...
src/Features/CSharp/Portable/UsePatternCombinators/CSharpUsePatternCombinatorsAnalyzer.cs
浏览文件 @
1ef362f0
...
...
@@ -4,7 +4,6 @@
#
nullable
enable
using
System.Diagnostics.CodeAnalysis
;
using
Microsoft.CodeAnalysis.CSharp.Syntax
;
using
Microsoft.CodeAnalysis.Operations
;
using
Roslyn.Utilities
;
...
...
@@ -16,14 +15,9 @@ namespace Microsoft.CodeAnalysis.CSharp.UsePatternCombinators
internal
static
class
CSharpUsePatternCombinatorsAnalyzer
{
public
static
bool
Analyze
(
IOperation
operation
,
[
NotNullWhen
(
true
)]
out
AnalyzedPattern
?
pattern
,
[
NotNullWhen
(
true
)]
out
ExpressionSyntax
?
target
)
public
static
AnalyzedPattern
?
Analyze
(
IOperation
operation
)
{
if
((
pattern
=
ParsePattern
(
operation
))
!=
null
)
return
TryGetTargetExpression
(
pattern
,
out
target
);
target
=
null
;
return
false
;
return
ParsePattern
(
operation
);
}
private
enum
ConstantResult
...
...
@@ -52,12 +46,7 @@ private enum ConstantResult
return
ParseConstantPattern
(
op
);
case
IBinaryOperation
{
OperatorKind
:
NotEquals
}
op
:
{
var
pattern
=
ParseConstantPattern
(
op
);
if
(
pattern
==
null
)
break
;
return
Not
.
Create
(
pattern
);
}
return
Not
.
Create
(
ParseConstantPattern
(
op
));
case
IBinaryOperation
{
OperatorKind
:
ConditionalOr
,
Syntax
:
BinaryExpressionSyntax
syntax
}
op
:
return
ParseBinaryPattern
(
op
,
isDisjunctive
:
true
,
syntax
.
OperatorToken
);
...
...
@@ -69,18 +58,13 @@ private enum ConstantResult
return
ParseRelationalPattern
(
op
);
case
IUnaryOperation
{
OperatorKind
:
UnaryOperatorKind
.
Not
}
op
:
{
var
pattern
=
ParsePattern
(
op
.
Operand
);
if
(
pattern
==
null
)
break
;
return
Not
.
Create
(
pattern
);
}
return
Not
.
Create
(
ParsePattern
(
op
.
Operand
));
case
IIsTypeOperation
{
Syntax
:
BinaryExpressionSyntax
{
Right
:
TypeSyntax
type
}
}
op
:
return
new
Type
(
type
,
op
.
ValueOperand
);
return
new
Type
(
type
,
GetTargetExpression
(
op
.
ValueOperand
)
);
case
IIsPatternOperation
{
Pattern
:
{
Syntax
:
PatternSyntax
pattern
}
}
op
:
return
new
Source
(
pattern
,
op
.
Value
);
return
new
Source
(
pattern
,
GetTargetExpression
(
op
.
Value
)
);
case
IParenthesizedOperation
op
:
return
ParsePattern
(
op
.
Operand
);
...
...
@@ -117,9 +101,9 @@ private static ConstantResult DetermineConstant(IBinaryOperation op)
return
DetermineConstant
(
op
)
switch
{
ConstantResult
.
Left
when
op
.
LeftOperand
.
Syntax
is
ExpressionSyntax
left
=>
new
Relational
(
Flip
(
op
.
OperatorKind
),
left
,
op
.
RightOperand
),
=>
new
Relational
(
Flip
(
op
.
OperatorKind
),
left
,
GetTargetExpression
(
op
.
RightOperand
)
),
ConstantResult
.
Right
when
op
.
RightOperand
.
Syntax
is
ExpressionSyntax
right
=>
new
Relational
(
op
.
OperatorKind
,
right
,
op
.
LeftOperand
),
=>
new
Relational
(
op
.
OperatorKind
,
right
,
GetTargetExpression
(
op
.
LeftOperand
)
),
_
=>
null
};
}
...
...
@@ -129,9 +113,9 @@ private static ConstantResult DetermineConstant(IBinaryOperation op)
return
DetermineConstant
(
op
)
switch
{
ConstantResult
.
Left
when
op
.
LeftOperand
.
Syntax
is
ExpressionSyntax
left
=>
new
Constant
(
left
,
op
.
RightOperand
),
=>
new
Constant
(
left
,
GetTargetExpression
(
op
.
RightOperand
)
),
ConstantResult
.
Right
when
op
.
RightOperand
.
Syntax
is
ExpressionSyntax
right
=>
new
Constant
(
right
,
op
.
LeftOperand
),
=>
new
Constant
(
right
,
GetTargetExpression
(
op
.
LeftOperand
)
),
_
=>
null
};
}
...
...
@@ -177,47 +161,14 @@ private static bool IsConstant(IOperation operation)
:
operation
.
ConstantValue
.
HasValue
;
}
private
static
bool
TryGetTargetExpression
(
AnalyzedPattern
pattern
,
[
NotNullWhen
(
true
)]
out
ExpressionSyntax
?
target
)
private
static
ExpressionSyntax
GetTargetExpression
(
IOperation
operation
)
{
target
=
null
;
#pragma warning disable CS8762 // Parameter must have a non-null value when exiting in some condition
.
return
CheckTargetExpressions
(
pattern
,
ref
target
);
#pragma warning restore CS8762 // Parameter must have a non-null value when exiting in some condition.
// Unwrap explicit casts because the pattern will emit those anyways.
// For instance, `(int)o == 123` would be the same as `o is 123`
.
if
(
operation
is
IConversionOperation
{
IsImplicit
:
false
}
op
)
operation
=
op
.
Operand
;
static
bool
CheckTargetExpressions
(
AnalyzedPattern
pattern
,
ref
ExpressionSyntax
?
target
)
{
return
pattern
switch
{
Test
p
=>
CheckTargetExpression
(
p
.
TargetOperation
,
ref
target
),
Binary
p
=>
CheckTargetExpressions
(
p
.
Left
,
ref
target
)
&&
CheckTargetExpressions
(
p
.
Right
,
ref
target
),
Not
p
=>
CheckTargetExpressions
(
p
.
Pattern
,
ref
target
),
var
p
=>
throw
ExceptionUtilities
.
UnexpectedValue
(
p
)
};
}
static
bool
CheckTargetExpression
(
IOperation
operation
,
ref
ExpressionSyntax
?
target
)
{
var
expr
=
GetTargetExpression
(
operation
);
if
(
expr
is
null
)
return
false
;
if
(
target
!=
null
)
return
SyntaxFactory
.
AreEquivalent
(
expr
,
target
);
target
=
expr
;
return
true
;
}
static
ExpressionSyntax
?
GetTargetExpression
(
IOperation
operation
)
{
// Unwrap explicit casts because the pattern will emit those anyways.
// For instance, `(int)o == 123` would be the same as `o is 123`.
if
(
operation
is
IConversionOperation
{
IsImplicit
:
false
}
op
)
operation
=
op
.
Operand
;
return
operation
.
Syntax
as
ExpressionSyntax
;
}
return
(
ExpressionSyntax
)
operation
.
Syntax
;
}
}
}
...
...
src/Features/CSharp/Portable/UsePatternCombinators/CSharpUsePatternCombinatorsCodeFixProvider.cs
浏览文件 @
1ef362f0
...
...
@@ -7,7 +7,6 @@
using
System
;
using
System.Collections.Immutable
;
using
System.Composition
;
using
System.Diagnostics
;
using
System.Diagnostics.CodeAnalysis
;
using
System.Linq
;
using
System.Threading
;
...
...
@@ -72,10 +71,10 @@ public override Task RegisterCodeFixesAsync(CodeFixContext context)
var
expression
=
editor
.
OriginalRoot
.
FindNode
(
location
.
SourceSpan
,
getInnermostNodeForTie
:
true
);
var
operation
=
semanticModel
.
GetOperation
(
expression
,
cancellationToken
);
RoslynDebug
.
AssertNotNull
(
operation
);
if
(!
CSharpUsePatternCombinatorsAnalyzer
.
Analyze
(
operation
,
out
var
pattern
,
out
var
target
))
Debug
.
Fail
(
"Analysis was expected to succeed."
);
var
pattern
=
CSharpUsePatternCombinatorsAnalyzer
.
Analyze
(
operation
);
RoslynDebug
.
AssertNotNull
(
pattern
);
var
patternSyntax
=
AsPatternSyntax
(
pattern
).
WithAdditionalAnnotations
(
Formatter
.
Annotation
);
editor
.
ReplaceNode
(
expression
,
IsPatternExpression
(
target
,
patternSyntax
));
editor
.
ReplaceNode
(
expression
,
IsPatternExpression
(
pattern
.
TargetExpression
,
patternSyntax
));
}
}
...
...
src/Features/CSharp/Portable/UsePatternCombinators/CSharpUsePatternCombinatorsDiagnosticAnalyzer.cs
浏览文件 @
1ef362f0
...
...
@@ -77,7 +77,8 @@ private void AnalyzeNode(SyntaxNodeAnalysisContext context)
if
(
operation
is
null
)
return
;
if
(!
CSharpUsePatternCombinatorsAnalyzer
.
Analyze
(
operation
,
out
var
pattern
,
target
:
out
_
))
var
pattern
=
CSharpUsePatternCombinatorsAnalyzer
.
Analyze
(
operation
);
if
(
pattern
is
null
)
return
;
if
(
IsTrivial
(
pattern
))
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录