Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
lwm1986
roslyn
提交
dff4233f
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,发现更多精彩内容 >>
提交
dff4233f
编写于
12月 12, 2016
作者:
T
Tomas Matousek
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Handle all expression-bodied members correctly in TryGetActiveTokens
上级
e4b04d35
变更
3
隐藏空白更改
内联
并排
Showing
3 changed file
with
439 addition
and
13 deletion
+439
-13
src/EditorFeatures/CSharpTest/EditAndContinue/LineEditTests.cs
...ditorFeatures/CSharpTest/EditAndContinue/LineEditTests.cs
+420
-0
src/Features/CSharp/Portable/EditAndContinue/CSharpEditAndContinueAnalyzer.cs
...Portable/EditAndContinue/CSharpEditAndContinueAnalyzer.cs
+5
-5
src/Features/CSharp/Portable/EditAndContinue/SyntaxUtilities.cs
...atures/CSharp/Portable/EditAndContinue/SyntaxUtilities.cs
+14
-8
未找到文件。
src/EditorFeatures/CSharpTest/EditAndContinue/LineEditTests.cs
浏览文件 @
dff4233f
...
...
@@ -488,6 +488,160 @@ public C(int a)
Array
.
Empty
<
string
>());
}
[
Fact
]
public
void
Constructor_ExpressionBodied_LineChange1
()
{
string
src1
=
@"
class C
{
int _a;
public C(int a) =>
_a = a;
}
"
;
string
src2
=
@"
class C
{
int _a;
public C(int a) =>
_a = a;
}"
;
var
edits
=
GetTopEdits
(
src1
,
src2
);
edits
.
VerifyLineEdits
(
new
[]
{
new
LineChange
(
5
,
6
)
},
Array
.
Empty
<
string
>());
}
[
Fact
]
public
void
Constructor_ExpressionBodied_LineChange2
()
{
string
src1
=
@"
class C
{
int _a;
public C(int a)
=> _a = a;
}
"
;
string
src2
=
@"
class C
{
int _a;
public C(int a)
=> _a = a;
}"
;
var
edits
=
GetTopEdits
(
src1
,
src2
);
edits
.
VerifyLineEdits
(
new
[]
{
new
LineChange
(
5
,
6
)
},
Array
.
Empty
<
string
>());
}
[
Fact
]
public
void
Constructor_ExpressionBodied_LineChange3
()
{
string
src1
=
@"
class C
{
int _a;
public C(int a) =>
_a = a;
}
"
;
string
src2
=
@"
class C
{
int _a;
public C(int a) =>
_a = a;
}"
;
var
edits
=
GetTopEdits
(
src1
,
src2
);
edits
.
VerifyLineEdits
(
new
[]
{
new
LineChange
(
5
,
6
)
},
Array
.
Empty
<
string
>());
}
[
Fact
]
public
void
Constructor_ExpressionBodied_LineChange4
()
{
string
src1
=
@"
class C
{
int _a;
public C(int a)
=>
_a = a;
}
"
;
string
src2
=
@"
class C
{
int _a;
public C(int a)
=>
_a = a;
}"
;
var
edits
=
GetTopEdits
(
src1
,
src2
);
edits
.
VerifyLineEdits
(
new
[]
{
new
LineChange
(
6
,
8
)
},
Array
.
Empty
<
string
>());
}
[
Fact
]
public
void
Constructor_ExpressionBodiedWithBase_LineChange1
()
{
string
src1
=
@"
class C
{
int _a;
public C(int a)
: base() => _a = a;
}
"
;
string
src2
=
@"
class C
{
int _a;
public C(int a)
: base() => _a = a;
}"
;
var
edits
=
GetTopEdits
(
src1
,
src2
);
edits
.
VerifyLineEdits
(
new
[]
{
new
LineChange
(
5
,
6
)
},
Array
.
Empty
<
string
>());
}
[
Fact
]
public
void
Constructor_ExpressionBodiedWithBase_Recompile1
()
{
string
src1
=
@"
class C
{
int _a;
public C(int a)
: base() =>
_a = a;
}
"
;
string
src2
=
@"
class C
{
int _a;
public C(int a)
: base() => _a = a;
}"
;
var
edits
=
GetTopEdits
(
src1
,
src2
);
edits
.
VerifyLineEdits
(
Array
.
Empty
<
LineChange
>(),
new
string
[]
{
"public C(int a)"
});
}
[
Fact
]
public
void
Constructor_Recompile1
()
{
...
...
@@ -570,6 +724,77 @@ public C(int a)
#
endregion
#
region
Destructors
[
Fact
]
public
void
Destructor_LineChange1
()
{
string
src1
=
@"
class C
{
~C()
{
}
}
"
;
string
src2
=
@"
class C
{
~C()
{
}
}"
;
var
edits
=
GetTopEdits
(
src1
,
src2
);
edits
.
VerifyLineEdits
(
new
[]
{
new
LineChange
(
5
,
4
)
},
Array
.
Empty
<
string
>());
}
[
Fact
]
public
void
Destructor_ExpressionBodied_LineChange1
()
{
string
src1
=
@"
class C
{
~C() => F();
}
"
;
string
src2
=
@"
class C
{
~C() =>
F();
}"
;
var
edits
=
GetTopEdits
(
src1
,
src2
);
edits
.
VerifyLineEdits
(
new
[]
{
new
LineChange
(
3
,
4
)
},
Array
.
Empty
<
string
>());
}
[
Fact
]
public
void
Destructor_ExpressionBodied_LineChange2
()
{
string
src1
=
@"
class C
{
~C() => F();
}
"
;
string
src2
=
@"
class C
{
~C()
=> F();
}"
;
var
edits
=
GetTopEdits
(
src1
,
src2
);
edits
.
VerifyLineEdits
(
new
[]
{
new
LineChange
(
3
,
4
)
},
Array
.
Empty
<
string
>());
}
#
endregion
#
region
Field
Initializers
[
Fact
]
...
...
@@ -935,6 +1160,48 @@ class C
Array
.
Empty
<
string
>());
}
[
Fact
]
public
void
Property_GetterExpressionBody1
()
{
string
src1
=
@"
class C
{
int P { get => 1; }
}
"
;
string
src2
=
@"
class C
{
int P { get =>
1; }
}"
;
var
edits
=
GetTopEdits
(
src1
,
src2
);
edits
.
VerifyLineEdits
(
new
[]
{
new
LineChange
(
3
,
4
)
},
Array
.
Empty
<
string
>());
}
[
Fact
]
public
void
Property_SetterExpressionBody1
()
{
string
src1
=
@"
class C
{
int P { set => F(); }
}
"
;
string
src2
=
@"
class C
{
int P { set =>
F(); }
}"
;
var
edits
=
GetTopEdits
(
src1
,
src2
);
edits
.
VerifyLineEdits
(
new
[]
{
new
LineChange
(
3
,
4
)
},
Array
.
Empty
<
string
>());
}
[
Fact
]
public
void
Property_Initializer1
()
{
...
...
@@ -998,5 +1265,158 @@ class C
}
#
endregion
#
region
Events
[
Fact
]
public
void
Event_LineChange1
()
{
string
src1
=
@"
class C
{
event Action E { add { } remove { } }
}
"
;
string
src2
=
@"
class C
{
event Action E { add { } remove { } }
}"
;
var
edits
=
GetTopEdits
(
src1
,
src2
);
edits
.
VerifyLineEdits
(
new
[]
{
new
LineChange
(
3
,
4
),
new
LineChange
(
3
,
4
)
},
Array
.
Empty
<
string
>());
}
[
Fact
]
public
void
EventAdder_LineChangeAndRecompile1
()
{
string
src1
=
@"
class C
{
event Action E { add {
} remove { } }
}
"
;
string
src2
=
@"
class C
{
event Action E { add { } remove { } }
}"
;
var
edits
=
GetTopEdits
(
src1
,
src2
);
edits
.
VerifyLineEdits
(
new
[]
{
new
LineChange
(
4
,
3
)
},
new
string
[]
{
"add { }"
});
}
[
Fact
]
public
void
EventRemover_Recompile1
()
{
string
src1
=
@"
class C
{
event Action E { add { } remove {
} }
}
"
;
string
src2
=
@"
class C
{
event Action E { add { } remove { } }
}"
;
var
edits
=
GetTopEdits
(
src1
,
src2
);
edits
.
VerifyLineEdits
(
Array
.
Empty
<
LineChange
>(),
new
string
[]
{
"remove { }"
});
}
[
Fact
]
public
void
EventAdder_LineChange1
()
{
string
src1
=
@"
class C
{
event Action E { add
{ } remove { } }
}
"
;
string
src2
=
@"
class C
{
event Action E { add { } remove { } }
}"
;
var
edits
=
GetTopEdits
(
src1
,
src2
);
edits
.
VerifyLineEdits
(
new
[]
{
new
LineChange
(
4
,
3
),
new
LineChange
(
4
,
3
)
},
Array
.
Empty
<
string
>());
}
[
Fact
]
public
void
EventRemover_LineChange1
()
{
string
src1
=
@"
class C
{
event Action E { add { } remove { } }
}
"
;
string
src2
=
@"
class C
{
event Action E { add { } remove
{ } }
}"
;
var
edits
=
GetTopEdits
(
src1
,
src2
);
edits
.
VerifyLineEdits
(
new
[]
{
new
LineChange
(
3
,
4
)
},
Array
.
Empty
<
string
>());
}
[
Fact
]
public
void
Event_ExpressionBody1
()
{
string
src1
=
@"
class C
{
event Action E { add => F(); remove => F(); }
}
"
;
string
src2
=
@"
class C
{
event Action E { add =>
F(); remove =>
F(); }
}"
;
var
edits
=
GetTopEdits
(
src1
,
src2
);
edits
.
VerifyLineEdits
(
new
[]
{
new
LineChange
(
3
,
4
),
new
LineChange
(
3
,
5
)
},
Array
.
Empty
<
string
>());
}
[
Fact
]
public
void
Event_ExpressionBody2
()
{
string
src1
=
@"
class C
{
event Action E { add
=> F(); remove
=> F(); }
}
"
;
string
src2
=
@"
class C
{
event Action E { add => F(); remove => F(); }
}"
;
var
edits
=
GetTopEdits
(
src1
,
src2
);
edits
.
VerifyLineEdits
(
new
[]
{
new
LineChange
(
4
,
3
),
new
LineChange
(
5
,
3
)
},
Array
.
Empty
<
string
>());
}
#
endregion
}
}
src/Features/CSharp/Portable/EditAndContinue/CSharpEditAndContinueAnalyzer.cs
浏览文件 @
dff4233f
...
...
@@ -150,7 +150,7 @@ where node.IsKind(SyntaxKind.IdentifierName)
/// <returns>
/// If <paramref name="node"/> is a method, accessor, operator, destructor, or constructor without an initializer,
/// tokens of its block body, or tokens of the expression body
if applicable
.
/// tokens of its block body, or tokens of the expression body.
///
/// If <paramref name="node"/> is an indexer declaration the tokens of its expression body.
///
...
...
@@ -197,18 +197,18 @@ internal override IEnumerable<SyntaxToken> TryGetActiveTokens(SyntaxNode node)
return
declarator
.
DescendantTokens
();
}
var
bodyTokens
=
SyntaxUtilities
.
TryGetMethodDeclarationBody
(
node
)?.
DescendantTokens
();
if
(
node
.
IsKind
(
SyntaxKind
.
ConstructorDeclaration
))
{
var
ctor
=
(
ConstructorDeclarationSyntax
)
node
;
if
(
ctor
.
Initializer
!=
null
)
{
return
ctor
.
Initializer
.
DescendantTokens
().
Concat
(
ctor
.
Body
.
DescendantTokens
()
);
bodyTokens
=
ctor
.
Initializer
.
DescendantTokens
().
Concat
(
bodyTokens
);
}
return
ctor
.
Body
.
DescendantTokens
();
}
return
SyntaxUtilities
.
TryGetMethodDeclarationBody
(
node
)?.
DescendantTokens
()
;
return
bodyTokens
;
}
protected
override
SyntaxNode
GetEncompassingAncestorImpl
(
SyntaxNode
bodyOrMatchRoot
)
...
...
src/Features/CSharp/Portable/EditAndContinue/SyntaxUtilities.cs
浏览文件 @
dff4233f
...
...
@@ -12,37 +12,43 @@ internal static class SyntaxUtilities
{
public
static
SyntaxNode
TryGetMethodDeclarationBody
(
SyntaxNode
node
)
{
SyntaxNode
BlockOrExpression
(
BlockSyntax
blockBodyOpt
,
ArrowExpressionClauseSyntax
expressionBodyOpt
)
=>
(
SyntaxNode
)
blockBodyOpt
??
expressionBodyOpt
?.
Expression
;
SyntaxNode
result
;
switch
(
node
.
Kind
())
{
case
SyntaxKind
.
MethodDeclaration
:
var
methodDeclaration
=
(
MethodDeclarationSyntax
)
node
;
result
=
(
SyntaxNode
)
methodDeclaration
.
Body
??
methodDeclaration
.
ExpressionBody
?.
Expression
;
result
=
BlockOrExpression
(
methodDeclaration
.
Body
,
methodDeclaration
.
ExpressionBody
)
;
break
;
case
SyntaxKind
.
ConversionOperatorDeclaration
:
var
conversionDeclaration
=
(
ConversionOperatorDeclarationSyntax
)
node
;
result
=
(
SyntaxNode
)
conversionDeclaration
.
Body
??
conversionDeclaration
.
ExpressionBody
?.
Expression
;
result
=
BlockOrExpression
(
conversionDeclaration
.
Body
,
conversionDeclaration
.
ExpressionBody
)
;
break
;
case
SyntaxKind
.
OperatorDeclaration
:
var
operatorDeclaration
=
(
OperatorDeclarationSyntax
)
node
;
result
=
(
SyntaxNode
)
operatorDeclaration
.
Body
??
operatorDeclaration
.
ExpressionBody
?.
Expression
;
result
=
BlockOrExpression
(
operatorDeclaration
.
Body
,
operatorDeclaration
.
ExpressionBody
)
;
break
;
case
SyntaxKind
.
SetAccessorDeclaration
:
case
SyntaxKind
.
AddAccessorDeclaration
:
case
SyntaxKind
.
RemoveAccessorDeclaration
:
case
SyntaxKind
.
GetAccessorDeclaration
:
result
=
((
AccessorDeclarationSyntax
)
node
).
Body
;
var
accessorDeclaration
=
(
AccessorDeclarationSyntax
)
node
;
result
=
BlockOrExpression
(
accessorDeclaration
.
Body
,
accessorDeclaration
.
ExpressionBody
);
break
;
case
SyntaxKind
.
ConstructorDeclaration
:
result
=
((
ConstructorDeclarationSyntax
)
node
).
Body
;
var
constructorDeclaration
=
(
ConstructorDeclarationSyntax
)
node
;
result
=
BlockOrExpression
(
constructorDeclaration
.
Body
,
constructorDeclaration
.
ExpressionBody
);
break
;
case
SyntaxKind
.
DestructorDeclaration
:
result
=
((
DestructorDeclarationSyntax
)
node
).
Body
;
var
destructorDeclaration
=
(
DestructorDeclarationSyntax
)
node
;
result
=
BlockOrExpression
(
destructorDeclaration
.
Body
,
destructorDeclaration
.
ExpressionBody
);
break
;
case
SyntaxKind
.
PropertyDeclaration
:
...
...
@@ -81,13 +87,13 @@ public static void AssertIsBody(SyntaxNode syntax, bool allowLambda)
return
;
}
//
method, constructor, destructor, operator, accessor
body
//
block
body
if
(
syntax
is
BlockSyntax
)
{
return
;
}
// expression body
of a method, operator, property, or indexer
// expression body
if
(
syntax
is
ExpressionSyntax
&&
syntax
.
Parent
is
ArrowExpressionClauseSyntax
)
{
return
;
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录