Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
lwm1986
roslyn
提交
8de57141
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,发现更多精彩内容 >>
提交
8de57141
编写于
11月 23, 2016
作者:
C
CyrusNajmabadi
浏览文件
操作
浏览文件
下载
差异文件
Merge remote-tracking branch 'upstream/master' into suggestionScrollBar
上级
77334ab1
e30afffa
变更
12
隐藏空白更改
内联
并排
Showing
12 changed file
with
187 addition
and
13 deletion
+187
-13
src/EditorFeatures/CSharpTest/InlineDeclaration/CSharpInlineDeclarationTests.cs
...arpTest/InlineDeclaration/CSharpInlineDeclarationTests.cs
+70
-0
src/EditorFeatures/CSharpTest/UseObjectInitializer/UseObjectInitializerTests.cs
...arpTest/UseObjectInitializer/UseObjectInitializerTests.cs
+15
-0
src/Features/CSharp/Portable/InlineDeclaration/CSharpInlineDeclarationDiagnosticAnalyzer.cs
...eDeclaration/CSharpInlineDeclarationDiagnosticAnalyzer.cs
+85
-1
src/Features/Core/Portable/UseCollectionInitializer/ObjectCreationExpressionAnalyzer.cs
...CollectionInitializer/ObjectCreationExpressionAnalyzer.cs
+1
-1
src/Features/Core/Portable/UseObjectInitializer/ObjectCreationExpressionAnalyzer.cs
.../UseObjectInitializer/ObjectCreationExpressionAnalyzer.cs
+1
-1
src/Workspaces/CSharp/Portable/CodeGeneration/CSharpFlagsEnumGenerator.cs
...Sharp/Portable/CodeGeneration/CSharpFlagsEnumGenerator.cs
+2
-3
src/Workspaces/CSharp/Portable/CodeGeneration/CSharpSyntaxGenerator.cs
...s/CSharp/Portable/CodeGeneration/CSharpSyntaxGenerator.cs
+2
-0
src/Workspaces/Core/Portable/Editing/SyntaxEditor.cs
src/Workspaces/Core/Portable/Editing/SyntaxEditor.cs
+8
-1
src/Workspaces/Core/Portable/Editing/SyntaxEditorExtensions.cs
...orkspaces/Core/Portable/Editing/SyntaxEditorExtensions.cs
+1
-1
src/Workspaces/VisualBasic/Portable/CodeGeneration/ExpressionGenerator.StringPiece.vb
...ortable/CodeGeneration/ExpressionGenerator.StringPiece.vb
+0
-1
src/Workspaces/VisualBasic/Portable/CodeGeneration/ExpressionGenerator.vb
...isualBasic/Portable/CodeGeneration/ExpressionGenerator.vb
+0
-1
src/Workspaces/VisualBasic/Portable/CodeGeneration/VisualBasicFlagsEnumGenerator.vb
.../Portable/CodeGeneration/VisualBasicFlagsEnumGenerator.vb
+2
-3
未找到文件。
src/EditorFeatures/CSharpTest/InlineDeclaration/CSharpInlineDeclarationTests.cs
浏览文件 @
8de57141
...
...
@@ -979,6 +979,76 @@ void M()
void Baz(out string s) { }
void Bar(Action a) { }
}"
);
}
[
WorkItem
(
15408
,
"https://github.com/dotnet/roslyn/issues/15408"
)]
[
Fact
,
Trait
(
Traits
.
Feature
,
Traits
.
Features
.
CodeActionsInlineDeclaration
)]
public
async
Task
TestDataFlow1
()
{
await
TestMissingAsync
(
@"
using System;
class C
{
void Foo(string x)
{
object [|s|] = null;
if (x != null || TryBaz(out s))
{
Console.WriteLine(s);
}
}
private bool TryBaz(out object s)
{
throw new NotImplementedException();
}
}"
);
}
[
WorkItem
(
15408
,
"https://github.com/dotnet/roslyn/issues/15408"
)]
[
Fact
,
Trait
(
Traits
.
Feature
,
Traits
.
Features
.
CodeActionsInlineDeclaration
)]
public
async
Task
TestDataFlow2
()
{
await
TestAsync
(
@"
using System;
class C
{
void Foo(string x)
{
object [|s|] = null;
if (x != null && TryBaz(out s))
{
Console.WriteLine(s);
}
}
private bool TryBaz(out object s)
{
throw new NotImplementedException();
}
}"
,
@"
using System;
class C
{
void Foo(string x)
{
if (x != null && TryBaz(out object s))
{
Console.WriteLine(s);
}
}
private bool TryBaz(out object s)
{
throw new NotImplementedException();
}
}"
);
}
}
...
...
src/EditorFeatures/CSharpTest/UseObjectInitializer/UseObjectInitializerTests.cs
浏览文件 @
8de57141
...
...
@@ -454,5 +454,20 @@ void M()
}"
,
compareTokens
:
false
);
}
[
WorkItem
(
15459
,
"https://github.com/dotnet/roslyn/issues/15459"
)]
[
Fact
,
Trait
(
Traits
.
Feature
,
Traits
.
Features
.
CodeActionsUseObjectInitializer
)]
public
async
Task
TestMissingInNonTopLevelObjectInitializer
()
{
await
TestMissingAsync
(
@"class C {
int a;
C Add(int x) {
var c = Add([||]new int());
c.a = 1;
return c;
}
}"
);
}
}
}
\ No newline at end of file
src/Features/CSharp/Portable/InlineDeclaration/CSharpInlineDeclarationDiagnosticAnalyzer.cs
浏览文件 @
8de57141
// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using
System
;
using
System.Collections.Immutable
;
using
System.Linq
;
using
System.Threading
;
...
...
@@ -8,6 +7,7 @@
using
Microsoft.CodeAnalysis.CSharp.Extensions
;
using
Microsoft.CodeAnalysis.CSharp.Syntax
;
using
Microsoft.CodeAnalysis.Diagnostics
;
using
Microsoft.CodeAnalysis.Shared.Extensions
;
namespace
Microsoft.CodeAnalysis.CSharp.InlineDeclaration
{
...
...
@@ -26,6 +26,8 @@ namespace Microsoft.CodeAnalysis.CSharp.InlineDeclaration
[
DiagnosticAnalyzer
(
LanguageNames
.
CSharp
)]
internal
class
CSharpInlineDeclarationDiagnosticAnalyzer
:
AbstractCodeStyleDiagnosticAnalyzer
{
private
const
string
CS0165
=
nameof
(
CS0165
);
// Use of unassigned local variable 's'
public
CSharpInlineDeclarationDiagnosticAnalyzer
()
:
base
(
IDEDiagnosticIds
.
InlineDeclarationDiagnosticId
,
new
LocalizableResourceString
(
nameof
(
FeaturesResources
.
Inline_variable_declaration
),
FeaturesResources
.
ResourceManager
,
typeof
(
FeaturesResources
)),
...
...
@@ -186,6 +188,15 @@ private void AnalyzeSyntaxNode(SyntaxNodeAnalysisContext context)
return
;
}
// See if inlining this variable would make it so that some variables were no
// longer definitely assigned.
if
(
WouldCauseDefiniteAssignmentErrors
(
semanticModel
,
localDeclarator
,
enclosingBlockOfLocalStatement
,
outSymbol
,
cancellationToken
))
{
return
;
}
// Collect some useful nodes for the fix provider to use so it doesn't have to
// find them again.
var
allLocations
=
ImmutableArray
.
Create
(
...
...
@@ -206,6 +217,79 @@ private void AnalyzeSyntaxNode(SyntaxNodeAnalysisContext context)
additionalLocations
:
allLocations
));
}
private
bool
WouldCauseDefiniteAssignmentErrors
(
SemanticModel
semanticModel
,
VariableDeclaratorSyntax
localDeclarator
,
BlockSyntax
enclosingBlock
,
ISymbol
outSymbol
,
CancellationToken
cancellationToken
)
{
// See if we have something like:
//
// int i = 0;
// if (Foo() || Bar(out i))
// {
// Console.WriteLine(i);
// }
//
// In this case, inlining the 'i' would cause it to longer be definitely
// assigned in the WriteLine invocation.
if
(
localDeclarator
.
Initializer
==
null
)
{
// Don't need to examine this unless the variable has an initializer.
return
false
;
}
// Find all the current read-references to the local.
var
query
=
from
t
in
enclosingBlock
.
DescendantTokens
()
where
t
.
Kind
()
==
SyntaxKind
.
IdentifierToken
where
t
.
ValueText
==
outSymbol
.
Name
let
id
=
t
.
Parent
as
IdentifierNameSyntax
where
id
!=
null
where
!
id
.
IsOnlyWrittenTo
()
let
symbol
=
semanticModel
.
GetSymbolInfo
(
id
).
GetAnySymbol
()
where
outSymbol
.
Equals
(
symbol
)
select
id
;
var
references
=
query
.
ToImmutableArray
<
SyntaxNode
>();
var
root
=
semanticModel
.
SyntaxTree
.
GetCompilationUnitRoot
(
cancellationToken
);
// Ensure we can track the references and the local variable as we make edits
// to the tree.
var
rootWithTrackedNodes
=
root
.
TrackNodes
(
references
.
Concat
(
localDeclarator
).
Concat
(
enclosingBlock
));
// Now, take the local variable and remove it's initializer. Then go to all
// the locations where we read from it. If they're definitely assigned, then
// that means the out-var did it's work and assigned the variable across all
// paths. If it's not definitely assigned, then we can't inline this variable.
var
currentLocalDeclarator
=
rootWithTrackedNodes
.
GetCurrentNode
(
localDeclarator
);
var
rootWithoutInitializer
=
rootWithTrackedNodes
.
ReplaceNode
(
currentLocalDeclarator
,
currentLocalDeclarator
.
WithInitializer
(
null
));
// Fork the compilation so we can do this analysis.
var
newCompilation
=
semanticModel
.
Compilation
.
ReplaceSyntaxTree
(
root
.
SyntaxTree
,
rootWithoutInitializer
.
SyntaxTree
);
var
newSemanticModel
=
newCompilation
.
GetSemanticModel
(
rootWithoutInitializer
.
SyntaxTree
);
// NOTE: there is no current compiler API to determine if a variable is definitely
// assigned or not. So, for now, we just get diagnostics for this block and see if
// we get any definite assigment errors where we have a reference to the symbol. If
// so, then we don't offer the fix.
var
currentBlock
=
rootWithoutInitializer
.
GetCurrentNode
(
enclosingBlock
);
var
diagnostics
=
newSemanticModel
.
GetDiagnostics
(
currentBlock
.
Span
,
cancellationToken
);
var
diagnosticSpans
=
diagnostics
.
Where
(
d
=>
d
.
Id
==
CS0165
)
.
Select
(
d
=>
d
.
Location
.
SourceSpan
)
.
Distinct
();
var
newReferenceSpans
=
rootWithoutInitializer
.
GetCurrentNodes
<
SyntaxNode
>(
references
)
.
Select
(
n
=>
n
.
Span
)
.
Distinct
();
return
diagnosticSpans
.
Intersect
(
newReferenceSpans
).
Any
();
}
private
SyntaxNode
GetOutArgumentScope
(
SyntaxNode
argumentExpression
)
{
for
(
var
current
=
argumentExpression
;
current
!=
null
;
current
=
current
.
Parent
)
...
...
src/Features/Core/Portable/UseCollectionInitializer/ObjectCreationExpressionAnalyzer.cs
浏览文件 @
8de57141
...
...
@@ -238,7 +238,7 @@ private bool TryInitializeVariableDeclarationCase()
return
false
;
}
var
containingDeclarator
=
_objectCreationExpression
.
FirstAncestorOrSelf
<
TVariableDeclaratorSyntax
>()
;
var
containingDeclarator
=
_objectCreationExpression
.
Parent
.
Parent
as
TVariableDeclaratorSyntax
;
if
(
containingDeclarator
==
null
)
{
return
false
;
...
...
src/Features/Core/Portable/UseObjectInitializer/ObjectCreationExpressionAnalyzer.cs
浏览文件 @
8de57141
...
...
@@ -248,7 +248,7 @@ private bool TryInitializeVariableDeclarationCase()
return
false
;
}
var
containingDeclarator
=
_objectCreationExpression
.
FirstAncestorOrSelf
<
TVariableDeclaratorSyntax
>()
;
var
containingDeclarator
=
_objectCreationExpression
.
Parent
.
Parent
as
TVariableDeclaratorSyntax
;
if
(
containingDeclarator
==
null
)
{
return
false
;
...
...
src/Workspaces/CSharp/Portable/CodeGeneration/CSharpFlagsEnumGenerator.cs
浏览文件 @
8de57141
...
...
@@ -20,7 +20,7 @@ namespace Microsoft.CodeAnalysis.CSharp.CodeGeneration
internal
class
CSharpFlagsEnumGenerator
:
AbstractFlagsEnumGenerator
{
internal
static
readonly
CSharpFlagsEnumGenerator
Instance
=
new
CSharpFlagsEnumGenerator
();
private
static
readonly
SyntaxGenerator
s_generatorInstance
=
new
CSharpSyntaxGenerator
()
;
private
static
readonly
SyntaxGenerator
s_generatorInstance
=
CSharpSyntaxGenerator
.
Instance
;
private
CSharpFlagsEnumGenerator
()
{
...
...
@@ -41,8 +41,7 @@ private CSharpFlagsEnumGenerator()
return
expression
;
}
var
factory
=
new
CSharpSyntaxGenerator
();
return
factory
.
CastExpression
(
enumType
,
expression
);
return
CSharpSyntaxGenerator
.
Instance
.
CastExpression
(
enumType
,
expression
);
}
protected
override
SyntaxGenerator
GetSyntaxGenerator
()
...
...
src/Workspaces/CSharp/Portable/CodeGeneration/CSharpSyntaxGenerator.cs
浏览文件 @
8de57141
...
...
@@ -21,6 +21,8 @@ internal class CSharpSyntaxGenerator : SyntaxGenerator
{
internal
override
SyntaxTrivia
CarriageReturnLineFeed
=>
SyntaxFactory
.
CarriageReturnLineFeed
;
public
static
readonly
SyntaxGenerator
Instance
=
new
CSharpSyntaxGenerator
();
#
region
Declarations
public
override
SyntaxNode
CompilationUnit
(
IEnumerable
<
SyntaxNode
>
declarations
)
{
...
...
src/Workspaces/Core/Portable/Editing/SyntaxEditor.cs
浏览文件 @
8de57141
...
...
@@ -29,6 +29,13 @@ public SyntaxEditor(SyntaxNode root, Workspace workspace)
_changes
=
new
List
<
Change
>();
}
internal
SyntaxEditor
(
SyntaxNode
root
,
SyntaxGenerator
generator
)
{
OriginalRoot
=
root
??
throw
new
ArgumentNullException
(
nameof
(
root
));
_generator
=
generator
;
_changes
=
new
List
<
Change
>();
}
/// <summary>
/// The <see cref="SyntaxNode"/> that was specified when the <see cref="SyntaxEditor"/> was constructed.
/// </summary>
...
...
@@ -280,4 +287,4 @@ public override SyntaxNode Apply(SyntaxNode root, SyntaxGenerator generator)
}
}
}
}
}
\ No newline at end of file
src/Workspaces/Core/Portable/Editing/SyntaxEditorExtensions.cs
浏览文件 @
8de57141
...
...
@@ -106,4 +106,4 @@ public static void AddBaseType(this SyntaxEditor editor, SyntaxNode declaration,
editor
.
ReplaceNode
(
declaration
,
(
d
,
g
)
=>
g
.
AddBaseType
(
d
,
baseType
));
}
}
}
}
\ No newline at end of file
src/Workspaces/VisualBasic/Portable/CodeGeneration/ExpressionGenerator.StringPiece.vb
浏览文件 @
8de57141
...
...
@@ -74,7 +74,6 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.CodeGeneration
End
Function
Private
Shared
Function
GenerateStringConstantExpression
(
name
As
String
)
As
MemberAccessExpressionSyntax
Dim
factory
=
New
VisualBasicSyntaxGenerator
()
Dim
result
=
GenerateMemberAccessExpression
(
"Microsoft"
,
"VisualBasic"
,
"Constants"
,
name
)
Return
result
.
WithAdditionalAnnotations
(
Simplifier
.
Annotation
)
...
...
src/Workspaces/VisualBasic/Portable/CodeGeneration/ExpressionGenerator.vb
浏览文件 @
8de57141
...
...
@@ -142,7 +142,6 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.CodeGeneration
End
Function
Private
Function
GenerateChrWExpression
(
c
As
Char
)
As
InvocationExpressionSyntax
Dim
factory
=
New
VisualBasicSyntaxGenerator
()
Dim
access
=
GenerateMemberAccessExpression
(
"Microsoft"
,
"VisualBasic"
,
"Strings"
,
"ChrW"
)
Dim
value
=
AscW
(
c
)
...
...
src/Workspaces/VisualBasic/Portable/CodeGeneration/VisualBasicFlagsEnumGenerator.vb
浏览文件 @
8de57141
...
...
@@ -17,7 +17,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.CodeGeneration
Inherits
AbstractFlagsEnumGenerator
Public
Shared
ReadOnly
Instance
As
VisualBasicFlagsEnumGenerator
=
New
VisualBasicFlagsEnumGenerator
Private
Shared
ReadOnly
s_syntaxGeneratorInstance
As
SyntaxGenerator
=
New
VisualBasicSyntaxGenerator
Private
Shared
ReadOnly
s_syntaxGeneratorInstance
As
SyntaxGenerator
=
VisualBasicSyntaxGenerator
.
Instance
Private
Sub
New
()
End
Sub
...
...
@@ -32,8 +32,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.CodeGeneration
Return
expression
End
If
Dim
factory
=
New
VisualBasicSyntaxGenerator
()
Return
factory
.
ConvertExpression
(
enumType
,
expression
)
Return
VisualBasicSyntaxGenerator
.
Instance
.
ConvertExpression
(
enumType
,
expression
)
End
Function
Protected
Overrides
Function
GetSyntaxGenerator
()
As
SyntaxGenerator
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录