Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
lwm1986
roslyn
提交
ee2f9864
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,发现更多精彩内容 >>
提交
ee2f9864
编写于
3月 02, 2020
作者:
C
Cyrus Najmabadi
浏览文件
操作
浏览文件
下载
差异文件
Merge remote-tracking branch 'upstream/master' into conflictMarkerFixAll
上级
db55807b
6389e251
变更
43
隐藏空白更改
内联
并排
Showing
43 changed file
with
464 addition
and
354 deletion
+464
-354
NuGet.config
NuGet.config
+2
-4
eng/Version.Details.xml
eng/Version.Details.xml
+2
-2
eng/Versions.props
eng/Versions.props
+2
-2
global.json
global.json
+1
-1
src/Compilers/VisualBasic/Portable/Binding/Binder.vb
src/Compilers/VisualBasic/Portable/Binding/Binder.vb
+1
-1
src/EditorFeatures/CSharp/DocumentationComments/XmlTagCompletionCommandHandler.cs
...p/DocumentationComments/XmlTagCompletionCommandHandler.cs
+3
-7
src/EditorFeatures/CSharpTest/CodeActions/InlineTemporary/InlineTemporaryTests.cs
...pTest/CodeActions/InlineTemporary/InlineTemporaryTests.cs
+26
-0
src/EditorFeatures/CSharpTest/Diagnostics/InvokeDelegateWithConditionalAccess/InvokeDelegateWithConditionalAccessTests.cs
...itionalAccess/InvokeDelegateWithConditionalAccessTests.cs
+130
-0
src/EditorFeatures/CSharpTest/TypeInferrer/TypeInferrerTests.cs
...itorFeatures/CSharpTest/TypeInferrer/TypeInferrerTests.cs
+24
-0
src/EditorFeatures/VisualBasicTest/TypeInferrer/TypeInferrerTests.vb
...eatures/VisualBasicTest/TypeInferrer/TypeInferrerTests.vb
+14
-0
src/Features/CSharp/Portable/CodeFixes/Nullable/CSharpDeclareAsNullableCodeFixProvider.cs
...eFixes/Nullable/CSharpDeclareAsNullableCodeFixProvider.cs
+4
-6
src/Features/CSharp/Portable/CodeRefactorings/InlineTemporary/InlineTemporaryCodeRefactoringProvider.cs
...InlineTemporary/InlineTemporaryCodeRefactoringProvider.cs
+5
-9
src/Features/CSharp/Portable/Completion/CompletionProviders/XmlDocCommentCompletionProvider.cs
...on/CompletionProviders/XmlDocCommentCompletionProvider.cs
+6
-4
src/Features/CSharp/Portable/ConvertLinq/ConvertForEachToLinqQuery/CSharpConvertForEachToLinqQueryProvider.cs
...achToLinqQuery/CSharpConvertForEachToLinqQueryProvider.cs
+2
-2
src/Features/CSharp/Portable/Debugging/CSharpProximityExpressionsService.Worker.cs
...ble/Debugging/CSharpProximityExpressionsService.Worker.cs
+3
-6
src/Features/CSharp/Portable/GenerateMember/GenerateDefaultConstructors/CSharpGenerateDefaultConstructorsService.cs
...tConstructors/CSharpGenerateDefaultConstructorsService.cs
+1
-2
src/Features/CSharp/Portable/GenerateMember/GenerateParameterizedMember/CSharpGenerateMethodService.cs
...enerateParameterizedMember/CSharpGenerateMethodService.cs
+1
-2
src/Features/CSharp/Portable/GenerateType/CSharpGenerateTypeService.cs
...CSharp/Portable/GenerateType/CSharpGenerateTypeService.cs
+6
-11
src/Features/CSharp/Portable/ImplementInterface/CSharpImplementInterfaceService.cs
...ble/ImplementInterface/CSharpImplementInterfaceService.cs
+2
-2
src/Features/CSharp/Portable/InvokeDelegateWithConditionalAccess/InvokeDelegateWithConditionalAccessAnalyzer.cs
...onalAccess/InvokeDelegateWithConditionalAccessAnalyzer.cs
+16
-0
src/Features/CSharp/Portable/UseLocalFunction/CSharpUseLocalFunctionDiagnosticAnalyzer.cs
...LocalFunction/CSharpUseLocalFunctionDiagnosticAnalyzer.cs
+12
-29
src/VisualStudio/CSharp/Impl/CodeModel/CSharpCodeModelService.cs
...ualStudio/CSharp/Impl/CodeModel/CSharpCodeModelService.cs
+2
-2
src/VisualStudio/Core/Def/Implementation/TaskList/CommentTaskTokenSerializer.cs
...Def/Implementation/TaskList/CommentTaskTokenSerializer.cs
+5
-6
src/VisualStudio/Core/Def/RoslynPackage.cs
src/VisualStudio/Core/Def/RoslynPackage.cs
+3
-3
src/Workspaces/CSharp/Portable/Classification/SyntaxClassification/SyntaxTokenClassifier.cs
...ssification/SyntaxClassification/SyntaxTokenClassifier.cs
+4
-6
src/Workspaces/CSharp/Portable/Extensions/DefaultExpressionSyntaxExtensions.cs
.../Portable/Extensions/DefaultExpressionSyntaxExtensions.cs
+3
-6
src/Workspaces/CSharp/Portable/Rename/CSharpRenameRewriterLanguageService.cs
...rp/Portable/Rename/CSharpRenameRewriterLanguageService.cs
+4
-20
src/Workspaces/CSharp/Portable/Simplification/CSharpSimplificationService.Expander.cs
...le/Simplification/CSharpSimplificationService.Expander.cs
+1
-2
src/Workspaces/CSharp/Portable/Simplification/Simplifiers/ExpressionSimplifier.cs
...rtable/Simplification/Simplifiers/ExpressionSimplifier.cs
+2
-2
src/Workspaces/CSharp/Portable/Simplification/Simplifiers/NameSimplifier.cs
...arp/Portable/Simplification/Simplifiers/NameSimplifier.cs
+9
-12
src/Workspaces/Core/Portable/Options/EditorConfig/EditorConfigDocumentOptionsProviderFactory.cs
...ditorConfig/EditorConfigDocumentOptionsProviderFactory.cs
+13
-21
src/Workspaces/Core/Portable/Workspace/Workspace.cs
src/Workspaces/Core/Portable/Workspace/Workspace.cs
+4
-0
src/Workspaces/SharedUtilitiesAndExtensions/Compiler/CSharp/Extensions/ExpressionSyntaxExtensions.cs
.../Compiler/CSharp/Extensions/ExpressionSyntaxExtensions.cs
+9
-19
src/Workspaces/SharedUtilitiesAndExtensions/Compiler/CSharp/Extensions/SimpleNameSyntaxExtensions.cs
.../Compiler/CSharp/Extensions/SimpleNameSyntaxExtensions.cs
+4
-4
src/Workspaces/SharedUtilitiesAndExtensions/Compiler/CSharp/Extensions/SyntaxNodeExtensions.cs
...nsions/Compiler/CSharp/Extensions/SyntaxNodeExtensions.cs
+21
-13
src/Workspaces/SharedUtilitiesAndExtensions/Compiler/CSharp/Services/SyntaxFacts/CSharpSyntaxFacts.cs
...Compiler/CSharp/Services/SyntaxFacts/CSharpSyntaxFacts.cs
+16
-27
src/Workspaces/SharedUtilitiesAndExtensions/Compiler/CSharp/Utilities/TypeStyle/CSharpUseExplicitTypeHelper.cs
...CSharp/Utilities/TypeStyle/CSharpUseExplicitTypeHelper.cs
+3
-6
src/Workspaces/SharedUtilitiesAndExtensions/Workspace/CSharp/Extensions/CastExpressionSyntaxExtensions.cs
...space/CSharp/Extensions/CastExpressionSyntaxExtensions.cs
+4
-4
src/Workspaces/SharedUtilitiesAndExtensions/Workspace/CSharp/Extensions/ContextQuery/SyntaxTokenExtensions.cs
...e/CSharp/Extensions/ContextQuery/SyntaxTokenExtensions.cs
+4
-10
src/Workspaces/SharedUtilitiesAndExtensions/Workspace/CSharp/Extensions/ContextQuery/SyntaxTreeExtensions.cs
...ce/CSharp/Extensions/ContextQuery/SyntaxTreeExtensions.cs
+14
-21
src/Workspaces/SharedUtilitiesAndExtensions/Workspace/CSharp/Extensions/ParenthesizedExpressionSyntaxExtensions.cs
...arp/Extensions/ParenthesizedExpressionSyntaxExtensions.cs
+24
-21
src/Workspaces/SharedUtilitiesAndExtensions/Workspace/CSharp/Extensions/SemanticModelExtensions.cs
...ns/Workspace/CSharp/Extensions/SemanticModelExtensions.cs
+8
-10
src/Workspaces/SharedUtilitiesAndExtensions/Workspace/CSharp/LanguageServices/CSharpTypeInferenceService.TypeInferrer.cs
...nguageServices/CSharpTypeInferenceService.TypeInferrer.cs
+44
-49
未找到文件。
NuGet.config
浏览文件 @
ee2f9864
...
...
@@ -5,6 +5,8 @@
<
clear
/>
<
add
key
=
"dotnet-core"
value
=
"https://dotnetfeed.blob.core.windows.net/dotnet-core/index.json"
/>
<
add
key
=
"dotnet-eng"
value
=
"https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-eng/nuget/v3/index.json"
/>
<
add
key
=
"dotnet-tools"
value
=
"https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-tools/nuget/v3/index.json"
/>
<
add
key
=
"dotnet5"
value
=
"https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet5/nuget/v3/index.json"
/>
<
add
key
=
"system-commandline"
value
=
"https://dotnet.myget.org/F/system-commandline/api/v3/index.json"
/>
<
add
key
=
"nuget.org"
value
=
"https://api.nuget.org/v3/index.json"
/>
<
add
key
=
"myget-dotnet-coreclr"
value
=
"https://dotnet.myget.org/F/dotnet-coreclr/api/v3/index.json"
/>
...
...
@@ -12,9 +14,6 @@
<
add
key
=
"dotnet-corefxtestdata"
value
=
"https://dotnet.myget.org/F/dotnet-corefxtestdata/api/v3/index.json"
/>
<
add
key
=
"dotnet-buildtools"
value
=
"https://dotnet.myget.org/F/dotnet-buildtools/api/v3/index.json"
/>
<
add
key
=
"experimental-vs-packages"
value
=
"https://dotnet.myget.org/F/experimental-vs-packages/api/v3/index.json"
/>
<
add
key
=
"symreader"
value
=
"https://dotnet.myget.org/F/symreader/api/v3/index.json"
/>
<
add
key
=
"symreader-portable"
value
=
"https://dotnet.myget.org/F/symreader-portable/api/v3/index.json"
/>
<
add
key
=
"symreader-converter"
value
=
"https://dotnet.myget.org/F/symreader-converter/api/v3/index.json"
/>
<
add
key
=
"symreader-native"
value
=
"https://dotnet.myget.org/F/symreader-native/api/v3/index.json"
/>
<
add
key
=
"metadata-tools"
value
=
"https://dotnet.myget.org/F/metadata-tools/api/v3/index.json"
/>
<
add
key
=
"interactive-window"
value
=
"https://dotnet.myget.org/F/interactive-window/api/v3/index.json"
/>
...
...
@@ -22,7 +21,6 @@
<
add
key
=
"roslyn-tools"
value
=
"https://dotnet.myget.org/F/roslyn-tools/api/v3/index.json"
/>
<
add
key
=
"roslyn-analyzers"
value
=
"https://dotnet.myget.org/F/roslyn-analyzers/api/v3/index.json"
/>
<
add
key
=
"roslyn"
value
=
"https://dotnet.myget.org/F/roslyn/api/v3/index.json"
/>
<
add
key
=
"sourcelink"
value
=
"https://dotnet.myget.org/F/sourcelink/api/v3/index.json"
/>
<
add
key
=
"vs-devcore"
value
=
"https://myget.org/F/vs-devcore/api/v3/index.json"
/>
<
add
key
=
"vs-editor"
value
=
"https://myget.org/F/vs-editor/api/v3/index.json"
/>
<
add
key
=
"roslyn_concord"
value
=
"https://myget.org/F/roslyn_concord/api/v3/index.json"
/>
...
...
eng/Version.Details.xml
浏览文件 @
ee2f9864
...
...
@@ -3,9 +3,9 @@
<ProductDependencies>
</ProductDependencies>
<ToolsetDependencies>
<Dependency
Name=
"Microsoft.DotNet.Arcade.Sdk"
Version=
"5.0.0-beta.201
29
.1"
>
<Dependency
Name=
"Microsoft.DotNet.Arcade.Sdk"
Version=
"5.0.0-beta.201
51
.1"
>
<Uri>
https://github.com/dotnet/arcade
</Uri>
<Sha>
8
6e54fb5076d46a6f959f0329d53c1c72e2280df
</Sha>
<Sha>
8
ccad075bbb0db445e03eed0a6073d27bdd4f31a
</Sha>
</Dependency>
</ToolsetDependencies>
</Dependencies>
eng/Versions.props
浏览文件 @
ee2f9864
...
...
@@ -69,8 +69,8 @@
<MicrosoftDiagnosticsRuntimeVersion>
0.8.31-beta
</MicrosoftDiagnosticsRuntimeVersion>
<MicrosoftDiagnosticsTracingTraceEventVersion>
1.0.35
</MicrosoftDiagnosticsTracingTraceEventVersion>
<MicrosoftDiaSymReaderVersion>
1.3.0
</MicrosoftDiaSymReaderVersion>
<MicrosoftDiaSymReaderConverterVersion>
1.1.0-beta2-
19409
-01
</MicrosoftDiaSymReaderConverterVersion>
<MicrosoftDiaSymReaderConverterXmlVersion>
1.1.0-beta2-
19409
-01
</MicrosoftDiaSymReaderConverterXmlVersion>
<MicrosoftDiaSymReaderConverterVersion>
1.1.0-beta2-
20115
-01
</MicrosoftDiaSymReaderConverterVersion>
<MicrosoftDiaSymReaderConverterXmlVersion>
1.1.0-beta2-
20115
-01
</MicrosoftDiaSymReaderConverterXmlVersion>
<MicrosoftDiaSymReaderNativeVersion>
1.7.0
</MicrosoftDiaSymReaderNativeVersion>
<MicrosoftDiaSymReaderPortablePdbVersion>
1.5.0
</MicrosoftDiaSymReaderPortablePdbVersion>
<MicrosoftDotNetVersionToolsVersion>
3.0.0-preview1-03617-02
</MicrosoftDotNetVersionToolsVersion>
...
...
global.json
浏览文件 @
ee2f9864
...
...
@@ -7,6 +7,6 @@
"xcopy-msbuild"
:
"16.4.0-alpha"
},
"msbuild-sdks"
:
{
"Microsoft.DotNet.Arcade.Sdk"
:
"5.0.0-beta.201
29
.1"
"Microsoft.DotNet.Arcade.Sdk"
:
"5.0.0-beta.201
51
.1"
}
}
src/Compilers/VisualBasic/Portable/Binding/Binder.vb
浏览文件 @
ee2f9864
...
...
@@ -746,7 +746,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic
End
Property
''' <summary>
''' True if integer overflow checking is
off
.
''' True if integer overflow checking is
On
.
''' </summary>
Public
Overridable
ReadOnly
Property
CheckOverflow
As
Boolean
Get
...
...
src/EditorFeatures/CSharp/DocumentationComments/XmlTagCompletionCommandHandler.cs
浏览文件 @
ee2f9864
...
...
@@ -67,14 +67,10 @@ protected override void TryCompleteTag(ITextView textView, ITextBuffer subjectBu
// We need to check for non-trivia XML text tokens after $$ that match the expected end tag text.
if
(
token
.
Parent
.
IsKind
(
SyntaxKind
.
XmlElementEndTag
)
&&
token
.
Parent
.
IsParentKind
(
SyntaxKind
.
XmlElement
))
token
.
Parent
.
IsParentKind
(
SyntaxKind
.
XmlElement
,
out
XmlElementSyntax
parentElement
)
&&
!
HasFollowingEndTagTrivia
(
parentElement
,
token
))
{
var
parentElement
=
token
.
Parent
.
Parent
as
XmlElementSyntax
;
if
(!
HasFollowingEndTagTrivia
(
parentElement
,
token
))
{
CheckNameAndInsertText
(
textView
,
subjectBuffer
,
position
,
parentElement
.
StartTag
,
null
,
"{0}>"
);
}
CheckNameAndInsertText
(
textView
,
subjectBuffer
,
position
,
parentElement
.
StartTag
,
null
,
"{0}>"
);
}
}
}
...
...
src/EditorFeatures/CSharpTest/CodeActions/InlineTemporary/InlineTemporaryTests.cs
浏览文件 @
ee2f9864
...
...
@@ -4851,6 +4851,32 @@ void Test()
}"
);
}
[
Fact
,
Trait
(
Traits
.
Feature
,
Traits
.
Features
.
CodeActionsInlineTemporary
)]
[
WorkItem
(
18322
,
"https://github.com/dotnet/roslyn/issues/18322"
)]
public
async
Task
TestInlineIntoExtensionMethodInvokedOnThis
()
{
await
TestInRegularAndScriptAsync
(
@"public class Class1
{
void M()
{
var [|c|] = 8;
this.DoStuff(c);
}
}
public static class Class1Extensions { public static void DoStuff(this Class1 c, int x) { } }"
,
@"public class Class1
{
void M()
{
this.DoStuff(8);
}
}
public static class Class1Extensions { public static void DoStuff(this Class1 c, int x) { } }"
);
}
[
WorkItem
(
8716
,
"https://github.com/dotnet/roslyn/issues/8716"
)]
[
Fact
,
Trait
(
Traits
.
Feature
,
Traits
.
Features
.
CodeActionsInlineTemporary
)]
public
async
Task
DoNotQualifyInlinedLocalFunction
()
...
...
src/EditorFeatures/CSharpTest/Diagnostics/InvokeDelegateWithConditionalAccess/InvokeDelegateWithConditionalAccessTests.cs
浏览文件 @
ee2f9864
...
...
@@ -757,6 +757,136 @@ int Goo()
return v();
}
}
}"
);
}
[
Fact
,
Trait
(
Traits
.
Feature
,
Traits
.
Features
.
CodeActionsInvokeDelegateWithConditionalAccess
)]
[
WorkItem
(
13226
,
"https://github.com/dotnet/roslyn/issues/13226"
)]
public
async
Task
TestWithLambdaInitializer
()
{
await
TestInRegularAndScript1Async
(
@"
using System;
class C
{
void Goo()
{
Action v = () => {};
[||]if (v != null)
{
v();
}
}
}"
,
@"
using System;
class C
{
void Goo()
{
Action v = () => {};
v?.Invoke();
}
}"
);
}
[
Fact
,
Trait
(
Traits
.
Feature
,
Traits
.
Features
.
CodeActionsInvokeDelegateWithConditionalAccess
)]
[
WorkItem
(
13226
,
"https://github.com/dotnet/roslyn/issues/13226"
)]
public
async
Task
TestWithLambdaInitializer2
()
{
await
TestInRegularAndScript1Async
(
@"
using System;
class C
{
void Goo()
{
Action v = (() => {});
[||]if (v != null)
{
v();
}
}
}"
,
@"
using System;
class C
{
void Goo()
{
Action v = (() => {});
v?.Invoke();
}
}"
);
}
[
Fact
,
Trait
(
Traits
.
Feature
,
Traits
.
Features
.
CodeActionsInvokeDelegateWithConditionalAccess
)]
[
WorkItem
(
13226
,
"https://github.com/dotnet/roslyn/issues/13226"
)]
public
async
Task
TestForWithAnonymousMethod
()
{
await
TestInRegularAndScript1Async
(
@"
using System;
class C
{
void Goo()
{
Action v = delegate {};
[||]if (v != null)
{
v();
}
}
}"
,
@"
using System;
class C
{
void Goo()
{
Action v = delegate {};
v?.Invoke();
}
}"
);
}
[
Fact
,
Trait
(
Traits
.
Feature
,
Traits
.
Features
.
CodeActionsInvokeDelegateWithConditionalAccess
)]
[
WorkItem
(
13226
,
"https://github.com/dotnet/roslyn/issues/13226"
)]
public
async
Task
TestWithMethodReference
()
{
await
TestInRegularAndScript1Async
(
@"
using System;
class C
{
void Goo()
{
Action v = Console.WriteLine;
[||]if (v != null)
{
v();
}
}
}"
,
@"
using System;
class C
{
void Goo()
{
Action v = Console.WriteLine;
v?.Invoke();
}
}"
);
}
}
...
...
src/EditorFeatures/CSharpTest/TypeInferrer/TypeInferrerTests.cs
浏览文件 @
ee2f9864
...
...
@@ -3081,5 +3081,29 @@ static void Main(string[] args)
await
TestAsync
(
text
,
"global::System.Object"
,
mode
);
}
[
WorkItem
(
14277
,
"https://github.com/dotnet/roslyn/issues/14277"
)]
[
Theory
,
CombinatorialData
,
Trait
(
Traits
.
Feature
,
Traits
.
Features
.
TypeInferenceService
)]
public
async
Task
TestValueInNestedTuple1
(
TestMode
mode
)
{
await
TestInMethodAsync
(
@"(int, (string, bool)) x = ([|Goo()|], ("""", true));"
,
"global::System.Int32"
,
mode
);
}
[
WorkItem
(
14277
,
"https://github.com/dotnet/roslyn/issues/14277"
)]
[
Theory
,
CombinatorialData
,
Trait
(
Traits
.
Feature
,
Traits
.
Features
.
TypeInferenceService
)]
public
async
Task
TestValueInNestedTuple2
(
TestMode
mode
)
{
await
TestInMethodAsync
(
@"(int, (string, bool)) x = (1, ("""", [|Goo()|]));"
,
"global::System.Boolean"
,
mode
);
}
[
WorkItem
(
14277
,
"https://github.com/dotnet/roslyn/issues/14277"
)]
[
Fact
,
Trait
(
Traits
.
Feature
,
Traits
.
Features
.
TypeInferenceService
)]
public
async
Task
TestValueInNestedTuple3
()
{
await
TestInMethodAsync
(
@"(int, string) x = (1, [||]);"
,
"global::System.String"
,
TestMode
.
Position
);
}
}
}
src/EditorFeatures/VisualBasicTest/TypeInferrer/TypeInferrerTests.vb
浏览文件 @
ee2f9864
...
...
@@ -700,6 +700,20 @@ End Class
Await
TestInMethodAsync
(
text
,
"System.Int32"
,
mode
)
End
Function
<
WorkItem
(
14277
,
"https://github.com/dotnet/roslyn/issues/14277"
)
>
<
Theory
,
CombinatorialData
,
Trait
(
Traits
.
Feature
,
Traits
.
Features
.
TypeInferenceService
)
>
Public
Async
Function
TestValueInNestedTuple1
(
mode
As
TestMode
)
As
Task
Await
TestInMethodAsync
(
"dim x as (integer, (string, boolean)) = ([|Goo()|], (
""""
, true));"
,
"global::System.Int32"
,
mode
)
End
Function
<
WorkItem
(
14277
,
"https://github.com/dotnet/roslyn/issues/14277"
)
>
<
Theory
,
CombinatorialData
,
Trait
(
Traits
.
Feature
,
Traits
.
Features
.
TypeInferenceService
)
>
Public
Async
Function
TestValueInNestedTuple2
(
mode
As
TestMode
)
As
Task
Await
TestInMethodAsync
(
"dim x as (integer, (string, boolean)) = (1, (
""""
, [|Goo()|]))"
,
"global::System.Boolean"
,
mode
)
End
Function
<
Fact
,
Trait
(
Traits
.
Feature
,
Traits
.
Features
.
TypeInferenceService
)
>
<
WorkItem
(
643
,
"https://github.com/dotnet/roslyn/issues/643"
)
>
Public
Async
Function
TestAwaitExpressionWithChainingMethod
()
As
Task
...
...
src/Features/CSharp/Portable/CodeFixes/Nullable/CSharpDeclareAsNullableCodeFixProvider.cs
浏览文件 @
ee2f9864
...
...
@@ -150,23 +150,21 @@ private static TypeSyntax TryGetDeclarationTypeToFix(SyntaxNode node)
}
// string x { get; set; } = null;
if
(
node
.
Parent
.
IsParentKind
(
SyntaxKind
.
PropertyDeclaration
)
==
true
)
if
(
node
.
Parent
.
IsParentKind
(
SyntaxKind
.
PropertyDeclaration
,
out
PropertyDeclarationSyntax
propertyDeclaration
)
)
{
var
propertyDeclaration
=
(
PropertyDeclarationSyntax
)
node
.
Parent
.
Parent
;
return
propertyDeclaration
.
Type
;
}
// void M(string x = null) { }
if
(
node
.
Parent
.
IsParentKind
(
SyntaxKind
.
Parameter
)
==
true
)
if
(
node
.
Parent
.
IsParentKind
(
SyntaxKind
.
Parameter
,
out
ParameterSyntax
parameter
)
)
{
var
parameter
=
(
ParameterSyntax
)
node
.
Parent
.
Parent
;
return
parameter
.
Type
;
}
// static string M() => null;
if
(
node
.
IsParentKind
(
SyntaxKind
.
ArrowExpressionClause
)
&&
node
.
Parent
.
IsParentKind
(
SyntaxKind
.
MethodDeclaration
))
if
(
node
.
IsParentKind
(
SyntaxKind
.
ArrowExpressionClause
)
&&
node
.
Parent
.
IsParentKind
(
SyntaxKind
.
MethodDeclaration
,
out
MethodDeclarationSyntax
arrowMethod
))
{
var
arrowMethod
=
(
MethodDeclarationSyntax
)
node
.
Parent
.
Parent
;
return
arrowMethod
.
ReturnType
;
}
...
...
src/Features/CSharp/Portable/CodeRefactorings/InlineTemporary/InlineTemporaryCodeRefactoringProvider.cs
浏览文件 @
ee2f9864
...
...
@@ -52,13 +52,12 @@ public override async Task ComputeRefactoringsAsync(CodeRefactoringContext conte
return
;
}
if
(!
variableDeclarator
.
IsParentKind
(
SyntaxKind
.
VariableDeclaration
)
||
if
(!
variableDeclarator
.
IsParentKind
(
SyntaxKind
.
VariableDeclaration
,
out
VariableDeclarationSyntax
variableDeclaration
)
||
!
variableDeclarator
.
Parent
.
IsParentKind
(
SyntaxKind
.
LocalDeclarationStatement
))
{
return
;
}
var
variableDeclaration
=
(
VariableDeclarationSyntax
)
variableDeclarator
.
Parent
;
if
(
variableDeclarator
.
Initializer
==
null
||
variableDeclarator
.
Initializer
.
Value
.
IsMissing
||
variableDeclarator
.
Initializer
.
Value
.
IsKind
(
SyntaxKind
.
StackAllocArrayCreationExpression
))
...
...
@@ -132,9 +131,8 @@ private static bool HasConflict(IdentifierNameSyntax identifier, VariableDeclara
identifierNode
=
identifier
;
}
if
(
identifierNode
.
IsParentKind
(
SyntaxKind
.
Argument
))
if
(
identifierNode
.
IsParentKind
(
SyntaxKind
.
Argument
,
out
ArgumentSyntax
argument
))
{
var
argument
=
(
ArgumentSyntax
)
identifierNode
.
Parent
;
if
(
argument
.
RefOrOutKeyword
.
Kind
()
!=
SyntaxKind
.
None
)
{
return
true
;
...
...
@@ -385,11 +383,9 @@ private SyntaxNode RemoveDeclaratorFromScope(VariableDeclaratorSyntax variableDe
// If the local is parented by a label statement, we can't remove this statement. Instead,
// we'll replace the local declaration with an empty expression statement.
if
(
newLocalDeclaration
.
IsParentKind
(
SyntaxKind
.
LabeledStatement
))
if
(
newLocalDeclaration
.
IsParentKind
(
SyntaxKind
.
LabeledStatement
,
out
LabeledStatementSyntax
labeledStatement
))
{
var
labeledStatement
=
(
LabeledStatementSyntax
)
newLocalDeclaration
.
Parent
;
var
newLabeledStatement
=
labeledStatement
.
ReplaceNode
(
newLocalDeclaration
,
SyntaxFactory
.
ParseStatement
(
""
));
return
newScope
.
ReplaceNode
(
labeledStatement
,
newLabeledStatement
);
}
...
...
@@ -582,9 +578,9 @@ private static bool IsInDeconstructionAssignmentLeft(ExpressionSyntax node)
{
return
false
;
}
else
if
(
parent
.
IsParentKind
(
SyntaxKind
.
SimpleAssignmentExpression
))
else
if
(
parent
.
IsParentKind
(
SyntaxKind
.
SimpleAssignmentExpression
,
out
AssignmentExpressionSyntax
assignment
))
{
return
((
AssignmentExpressionSyntax
)
parent
.
Parent
)
.
Left
==
parent
;
return
assignment
.
Left
==
parent
;
}
parent
=
parent
.
Parent
;
...
...
src/Features/CSharp/Portable/Completion/CompletionProviders/XmlDocCommentCompletionProvider.cs
浏览文件 @
ee2f9864
...
...
@@ -251,15 +251,17 @@ private bool IsAttributeValueContext(SyntaxToken token, out string tagName, out
{
XmlAttributeSyntax
attributeSyntax
=
null
;
if
(
token
.
Parent
.
IsKind
(
SyntaxKind
.
IdentifierName
)
&&
token
.
Parent
.
IsParentKind
(
SyntaxKind
.
XmlNameAttribute
))
if
(
token
.
Parent
.
IsKind
(
SyntaxKind
.
IdentifierName
)
&&
token
.
Parent
.
IsParentKind
(
SyntaxKind
.
XmlNameAttribute
,
out
XmlNameAttributeSyntax
xmlName
))
{
// Handle the special 'name' attributes: name="bar$$
attributeSyntax
=
(
XmlNameAttributeSyntax
)
token
.
Parent
.
Parent
;
attributeSyntax
=
xmlName
;
}
else
if
(
token
.
IsKind
(
SyntaxKind
.
XmlTextLiteralToken
)
&&
token
.
Parent
.
IsKind
(
SyntaxKind
.
XmlTextAttribute
))
else
if
(
token
.
IsKind
(
SyntaxKind
.
XmlTextLiteralToken
)
&&
token
.
Parent
.
IsKind
(
SyntaxKind
.
XmlTextAttribute
,
out
XmlTextAttributeSyntax
xmlText
))
{
// Handle the other general text attributes: foo="bar$$
attributeSyntax
=
(
XmlTextAttributeSyntax
)
token
.
Paren
t
;
attributeSyntax
=
xmlTex
t
;
}
else
if
(
token
.
Parent
.
IsKind
(
SyntaxKind
.
XmlNameAttribute
)
||
token
.
Parent
.
IsKind
(
SyntaxKind
.
XmlTextAttribute
))
{
...
...
src/Features/CSharp/Portable/ConvertLinq/ConvertForEachToLinqQuery/CSharpConvertForEachToLinqQueryProvider.cs
浏览文件 @
ee2f9864
...
...
@@ -287,13 +287,13 @@ bool TryProcessLocalDeclarationStatement(LocalDeclarationStatementSyntax localDe
.
Where
(
statement
=>
Equals
(
semanticModel
.
GetEnclosingSymbol
(
statement
.
SpanStart
,
cancellationToken
),
memberDeclarationSymbol
)).
Count
();
if
(
forEachInfo
.
ForEachStatement
.
IsParentKind
(
SyntaxKind
.
Block
)
&&
if
(
forEachInfo
.
ForEachStatement
.
IsParentKind
(
SyntaxKind
.
Block
,
out
BlockSyntax
block
)
&&
forEachInfo
.
ForEachStatement
.
Parent
.
Parent
==
memberDeclarationSyntax
)
{
// Check that
// a. There are either just a single 'yield return' or 'yield return' with 'yield break' just after.
// b. Those foreach and 'yield break' (if exists) are last statements in the method (do not count local function declaration statements).
var
statementsOnBlockWithForEach
=
((
BlockSyntax
)
forEachInfo
.
ForEachStatement
.
Parent
)
.
Statements
var
statementsOnBlockWithForEach
=
block
.
Statements
.
Where
(
statement
=>
statement
.
Kind
()
!=
SyntaxKind
.
LocalFunctionStatement
).
ToArray
();
var
lastNonLocalFunctionStatement
=
statementsOnBlockWithForEach
.
Last
();
if
(
yieldStatementsCount
==
1
&&
lastNonLocalFunctionStatement
==
forEachInfo
.
ForEachStatement
)
...
...
src/Features/CSharp/Portable/Debugging/CSharpProximityExpressionsService.Worker.cs
浏览文件 @
ee2f9864
...
...
@@ -79,13 +79,10 @@ private void AddCatchParameters()
var
block
=
GetImmediatelyContainingBlock
();
// if we're the start of a "catch(Goo e)" clause, then add "e".
if
(
block
!=
null
&&
block
.
IsParentKind
(
SyntaxKind
.
CatchClause
))
if
(
block
!=
null
&&
block
.
IsParentKind
(
SyntaxKind
.
CatchClause
,
out
CatchClauseSyntax
catchClause
)
&&
catchClause
.
Declaration
!=
null
&&
catchClause
.
Declaration
.
Identifier
.
Kind
()
!=
SyntaxKind
.
None
)
{
var
catchClause
=
(
CatchClauseSyntax
)
block
.
Parent
;
if
(
catchClause
.
Declaration
!=
null
&&
catchClause
.
Declaration
.
Identifier
.
Kind
()
!=
SyntaxKind
.
None
)
{
_expressions
.
Add
(
catchClause
.
Declaration
.
Identifier
.
ValueText
);
}
_expressions
.
Add
(
catchClause
.
Declaration
.
Identifier
.
ValueText
);
}
}
...
...
src/Features/CSharp/Portable/GenerateMember/GenerateDefaultConstructors/CSharpGenerateDefaultConstructorsService.cs
浏览文件 @
ee2f9864
...
...
@@ -43,9 +43,8 @@ public CSharpGenerateDefaultConstructorsService()
var
node
=
semanticDocument
.
Root
.
FindToken
(
textSpan
.
Start
).
GetAncestor
<
TypeSyntax
>();
if
(
node
!=
null
)
{
if
(
node
.
Parent
is
BaseTypeSyntax
&&
node
.
Parent
.
IsParentKind
(
SyntaxKind
.
BaseList
))
if
(
node
.
Parent
is
BaseTypeSyntax
&&
node
.
Parent
.
IsParentKind
(
SyntaxKind
.
BaseList
,
out
BaseListSyntax
baseList
))
{
var
baseList
=
(
BaseListSyntax
)
node
.
Parent
.
Parent
;
if
(
baseList
.
Types
.
Count
>
0
&&
baseList
.
Types
[
0
].
Type
==
node
&&
baseList
.
IsParentKind
(
SyntaxKind
.
ClassDeclaration
))
...
...
src/Features/CSharp/Portable/GenerateMember/GenerateParameterizedMember/CSharpGenerateMethodService.cs
浏览文件 @
ee2f9864
...
...
@@ -107,9 +107,8 @@ protected override bool IsValidSymbol(ISymbol symbol, SemanticModel semanticMode
if
(
memberAccess
==
null
||
memberAccess
.
Name
==
simpleName
)
{
if
(
simpleNameOrMemberAccessExpression
.
IsParentKind
(
SyntaxKind
.
InvocationExpression
))
if
(
simpleNameOrMemberAccessExpression
.
IsParentKind
(
SyntaxKind
.
InvocationExpression
,
out
invocationExpressionOpt
))
{
invocationExpressionOpt
=
(
InvocationExpressionSyntax
)
simpleNameOrMemberAccessExpression
.
Parent
;
isInConditionalAccessExpression
=
inConditionalMemberAccess
;
return
!
invocationExpressionOpt
.
ArgumentList
.
CloseParenToken
.
IsMissing
;
}
...
...
src/Features/CSharp/Portable/GenerateType/CSharpGenerateTypeService.cs
浏览文件 @
ee2f9864
...
...
@@ -62,9 +62,8 @@ protected override bool IsArrayElementType(ExpressionSyntax expression)
ExpressionSyntax
expression
,
CancellationToken
cancellationToken
)
{
if
(
expression
is
TypeSyntax
&&
expression
.
IsParentKind
(
SyntaxKind
.
TypeArgumentList
))
if
(
expression
is
TypeSyntax
&&
expression
.
IsParentKind
(
SyntaxKind
.
TypeArgumentList
,
out
TypeArgumentListSyntax
typeArgumentList
))
{
var
typeArgumentList
=
(
TypeArgumentListSyntax
)
expression
.
Parent
;
var
symbolInfo
=
semanticModel
.
GetSymbolInfo
(
typeArgumentList
.
Parent
,
cancellationToken
);
var
symbol
=
symbolInfo
.
GetAnySymbol
();
if
(
symbol
.
IsConstructor
())
...
...
@@ -94,12 +93,10 @@ protected override bool IsArrayElementType(ExpressionSyntax expression)
protected
override
bool
IsInInterfaceList
(
ExpressionSyntax
expression
)
{
if
(
expression
is
TypeSyntax
&&
expression
.
Parent
is
BaseTypeSyntax
&&
expression
.
Parent
.
IsParentKind
(
SyntaxKind
.
BaseList
)
&&
((
BaseTypeSyntax
)
expression
.
Parent
)
.
Type
==
expression
)
expression
.
Parent
is
BaseTypeSyntax
baseType
&&
expression
.
Parent
.
IsParentKind
(
SyntaxKind
.
BaseList
,
out
BaseListSyntax
baseList
)
&&
baseType
.
Type
==
expression
)
{
var
baseList
=
(
BaseListSyntax
)
expression
.
Parent
.
Parent
;
// If it's after the first item, then it's definitely an interface.
if
(
baseList
.
Types
[
0
]
!=
expression
.
Parent
)
{
...
...
@@ -114,11 +111,9 @@ protected override bool IsInInterfaceList(ExpressionSyntax expression)
}
if
(
expression
is
TypeSyntax
&&
expression
.
IsParentKind
(
SyntaxKind
.
TypeConstraint
)
&&
expression
.
Parent
.
IsParentKind
(
SyntaxKind
.
TypeParameterConstraintClause
))
expression
.
IsParentKind
(
SyntaxKind
.
TypeConstraint
,
out
TypeConstraintSyntax
typeConstraint
)
&&
expression
.
Parent
.
IsParentKind
(
SyntaxKind
.
TypeParameterConstraintClause
,
out
TypeParameterConstraintClauseSyntax
constraintClause
))
{
var
typeConstraint
=
(
TypeConstraintSyntax
)
expression
.
Parent
;
var
constraintClause
=
(
TypeParameterConstraintClauseSyntax
)
typeConstraint
.
Parent
;
var
index
=
constraintClause
.
Constraints
.
IndexOf
(
typeConstraint
);
// If it's after the first item, then it's definitely an interface.
...
...
src/Features/CSharp/Portable/ImplementInterface/CSharpImplementInterfaceService.cs
浏览文件 @
ee2f9864
...
...
@@ -32,9 +32,9 @@ public CSharpImplementInterfaceService()
{
if
(!
cancellationToken
.
IsCancellationRequested
)
{
if
(
node
is
TypeSyntax
interfaceNode
&&
interfaceNode
.
Parent
is
BaseTypeSyntax
&&
if
(
node
is
TypeSyntax
interfaceNode
&&
interfaceNode
.
Parent
is
BaseTypeSyntax
baseType
&&
interfaceNode
.
Parent
.
IsParentKind
(
SyntaxKind
.
BaseList
)
&&
((
BaseTypeSyntax
)
interfaceNode
.
Parent
)
.
Type
==
interfaceNode
)
baseType
.
Type
==
interfaceNode
)
{
if
(
interfaceNode
.
Parent
.
Parent
.
IsParentKind
(
SyntaxKind
.
ClassDeclaration
)
||
interfaceNode
.
Parent
.
Parent
.
IsParentKind
(
SyntaxKind
.
StructDeclaration
))
...
...
src/Features/CSharp/Portable/InvokeDelegateWithConditionalAccess/InvokeDelegateWithConditionalAccessAnalyzer.cs
浏览文件 @
ee2f9864
...
...
@@ -9,6 +9,7 @@
using
Microsoft.CodeAnalysis.CSharp.Extensions
;
using
Microsoft.CodeAnalysis.CSharp.Syntax
;
using
Microsoft.CodeAnalysis.Diagnostics
;
using
Microsoft.CodeAnalysis.Shared.Extensions
;
using
Microsoft.CodeAnalysis.Text
;
namespace
Microsoft.CodeAnalysis.CSharp.InvokeDelegateWithConditionalAccess
...
...
@@ -265,6 +266,21 @@ private void SyntaxNodeAction(SyntaxNodeAnalysisContext syntaxContext)
// Syntactically this looks good. Now make sure that the local is a delegate type.
var
semanticModel
=
syntaxContext
.
SemanticModel
;
// The initializer can't be inlined if it's an actual lambda/method reference.
// These cannot be invoked with `?.` (only delegate *values* can be).
var
initializer
=
declarator
.
Initializer
.
Value
.
WalkDownParentheses
();
if
(
initializer
.
IsAnyLambdaOrAnonymousMethod
())
{
return
false
;
}
var
initializerSymbol
=
semanticModel
.
GetSymbolInfo
(
initializer
,
cancellationToken
).
GetAnySymbol
();
if
(
initializerSymbol
is
IMethodSymbol
)
{
return
false
;
}
var
localSymbol
=
(
ILocalSymbol
)
semanticModel
.
GetDeclaredSymbol
(
declarator
,
cancellationToken
);
// Ok, we made a local just to check it for null and invoke it. Looks like something
...
...
src/Features/CSharp/Portable/UseLocalFunction/CSharpUseLocalFunctionDiagnosticAnalyzer.cs
浏览文件 @
ee2f9864
...
...
@@ -85,8 +85,7 @@ private void SyntaxNodeAction(SyntaxNodeAnalysisContext syntaxContext, INamedTyp
var
anonymousFunction
=
(
AnonymousFunctionExpressionSyntax
)
syntaxContext
.
Node
;
var
semanticModel
=
syntaxContext
.
SemanticModel
;
if
(!
CheckForPattern
(
semanticModel
,
anonymousFunction
,
cancellationToken
,
out
var
localDeclaration
))
if
(!
CheckForPattern
(
anonymousFunction
,
out
var
localDeclaration
))
{
return
;
}
...
...
@@ -170,10 +169,7 @@ private void SyntaxNodeAction(SyntaxNodeAnalysisContext syntaxContext, INamedTyp
}
private
bool
CheckForPattern
(
SemanticModel
semanticModel
,
AnonymousFunctionExpressionSyntax
anonymousFunction
,
CancellationToken
cancellationToken
,
out
LocalDeclarationStatementSyntax
localDeclaration
)
AnonymousFunctionExpressionSyntax
anonymousFunction
,
out
LocalDeclarationStatementSyntax
localDeclaration
)
{
// Look for:
//
...
...
@@ -182,24 +178,20 @@ private void SyntaxNodeAction(SyntaxNodeAnalysisContext syntaxContext, INamedTyp
//
// Type t = null;
// t = <anonymous function>
return
CheckForSimpleLocalDeclarationPattern
(
semanticModel
,
anonymousFunction
,
cancellationToke
n
,
out
localDeclaration
)
||
CheckForCastedLocalDeclarationPattern
(
semanticModel
,
anonymousFunction
,
cancellationToke
n
,
out
localDeclaration
)
||
CheckForLocalDeclarationAndAssignment
(
semanticModel
,
anonymousFunction
,
cancellationToke
n
,
out
localDeclaration
);
return
CheckForSimpleLocalDeclarationPattern
(
anonymousFunctio
n
,
out
localDeclaration
)
||
CheckForCastedLocalDeclarationPattern
(
anonymousFunctio
n
,
out
localDeclaration
)
||
CheckForLocalDeclarationAndAssignment
(
anonymousFunctio
n
,
out
localDeclaration
);
}
private
bool
CheckForSimpleLocalDeclarationPattern
(
SemanticModel
semanticModel
,
AnonymousFunctionExpressionSyntax
anonymousFunction
,
CancellationToken
cancellationToken
,
out
LocalDeclarationStatementSyntax
localDeclaration
)
AnonymousFunctionExpressionSyntax
anonymousFunction
,
out
LocalDeclarationStatementSyntax
localDeclaration
)
{
// Type t = <anonymous function>
if
(
anonymousFunction
.
IsParentKind
(
SyntaxKind
.
EqualsValueClause
)
&&
anonymousFunction
.
Parent
.
IsParentKind
(
SyntaxKind
.
VariableDeclarator
)
&&
anonymousFunction
.
Parent
.
Parent
.
IsParentKind
(
SyntaxKind
.
VariableDeclaration
)
&&
anonymousFunction
.
Parent
.
Parent
.
Parent
.
IsParentKind
(
SyntaxKind
.
LocalDeclarationStatement
))
anonymousFunction
.
Parent
.
Parent
.
Parent
.
IsParentKind
(
SyntaxKind
.
LocalDeclarationStatement
,
out
localDeclaration
))
{
localDeclaration
=
(
LocalDeclarationStatementSyntax
)
anonymousFunction
.
Parent
.
Parent
.
Parent
.
Parent
;
if
(!
localDeclaration
.
Declaration
.
Type
.
IsVar
)
{
return
true
;
...
...
@@ -295,10 +287,7 @@ private void SyntaxNodeAction(SyntaxNodeAnalysisContext syntaxContext, INamedTyp
}
private
bool
CheckForCastedLocalDeclarationPattern
(
SemanticModel
semanticModel
,
AnonymousFunctionExpressionSyntax
anonymousFunction
,
CancellationToken
cancellationToken
,
out
LocalDeclarationStatementSyntax
localDeclaration
)
AnonymousFunctionExpressionSyntax
anonymousFunction
,
out
LocalDeclarationStatementSyntax
localDeclaration
)
{
// var t = (Type)(<anonymous function>)
var
containingStatement
=
anonymousFunction
.
GetAncestor
<
StatementSyntax
>();
...
...
@@ -327,22 +316,16 @@ private void SyntaxNodeAction(SyntaxNodeAnalysisContext syntaxContext, INamedTyp
}
private
bool
CheckForLocalDeclarationAndAssignment
(
SemanticModel
semanticModel
,
AnonymousFunctionExpressionSyntax
anonymousFunction
,
CancellationToken
cancellationToken
,
out
LocalDeclarationStatementSyntax
localDeclaration
)
AnonymousFunctionExpressionSyntax
anonymousFunction
,
out
LocalDeclarationStatementSyntax
localDeclaration
)
{
// Type t = null;
// t = <anonymous function>
if
(
anonymousFunction
.
IsParentKind
(
SyntaxKind
.
SimpleAssignmentExpression
)
&&
anonymousFunction
.
Parent
.
IsParentKind
(
SyntaxKind
.
ExpressionStatement
)
&&
anonymousFunction
.
Parent
.
Parent
.
IsParentKind
(
SyntaxKind
.
Block
))
if
(
anonymousFunction
.
IsParentKind
(
SyntaxKind
.
SimpleAssignmentExpression
,
out
AssignmentExpressionSyntax
assignment
)
&&
anonymousFunction
.
Parent
.
IsParentKind
(
SyntaxKind
.
ExpressionStatement
,
out
ExpressionStatementSyntax
expressionStatement
)
&&
anonymousFunction
.
Parent
.
Parent
.
IsParentKind
(
SyntaxKind
.
Block
,
out
BlockSyntax
block
))
{
var
assignment
=
(
AssignmentExpressionSyntax
)
anonymousFunction
.
Parent
;
if
(
assignment
.
Left
.
IsKind
(
SyntaxKind
.
IdentifierName
))
{
var
expressionStatement
=
(
ExpressionStatementSyntax
)
assignment
.
Parent
;
var
block
=
(
BlockSyntax
)
expressionStatement
.
Parent
;
var
expressionStatementIndex
=
block
.
Statements
.
IndexOf
(
expressionStatement
);
if
(
expressionStatementIndex
>=
1
)
{
...
...
src/VisualStudio/CSharp/Impl/CodeModel/CSharpCodeModelService.cs
浏览文件 @
ee2f9864
...
...
@@ -3587,8 +3587,8 @@ private static bool IsAutoImplementedProperty(PropertyDeclarationSyntax property
private
static
bool
IsExtensionMethod
(
MethodDeclarationSyntax
methodDeclaration
)
{
if
(!
methodDeclaration
.
IsParentKind
(
SyntaxKind
.
ClassDeclaration
)
||
!
((
ClassDeclarationSyntax
)
methodDeclaration
.
Parent
)
.
Modifiers
.
Any
(
SyntaxKind
.
StaticKeyword
))
if
(!
methodDeclaration
.
IsParentKind
(
SyntaxKind
.
ClassDeclaration
,
out
ClassDeclarationSyntax
classDecl
)
||
!
classDecl
.
Modifiers
.
Any
(
SyntaxKind
.
StaticKeyword
))
{
return
false
;
}
...
...
src/VisualStudio/Core/Def/Implementation/TaskList/CommentTaskTokenSerializer.cs
浏览文件 @
ee2f9864
...
...
@@ -16,17 +16,17 @@ namespace Microsoft.VisualStudio.LanguageServices.Implementation.TaskList
[
Export
(
typeof
(
IOptionPersister
))]
internal
class
CommentTaskTokenSerializer
:
IOptionPersister
{
private
readonly
VisualStudioWorkspace
_workspace
;
private
readonly
ITaskList
_taskList
;
private
readonly
IGlobalOptionService
_globalOptionService
;
private
string
_lastCommentTokenCache
=
null
;
[
ImportingConstructor
]
public
CommentTaskTokenSerializer
(
VisualStudioWorkspace
workspa
ce
,
IGlobalOptionService
globalOptionServi
ce
,
[
Import
(
typeof
(
SVsServiceProvider
))]
IServiceProvider
serviceProvider
)
{
_
workspace
=
workspa
ce
;
_
globalOptionService
=
globalOptionServi
ce
;
// The SVsTaskList may not be available or doesn't actually implement ITaskList
// in the "devenv /build" scenario
...
...
@@ -68,8 +68,7 @@ private void OnPropertyChanged(object sender, PropertyChangedEventArgs e)
var
commentString
=
GetTaskTokenList
(
_taskList
);
var
optionSet
=
_workspace
.
Options
;
var
optionValue
=
optionSet
.
GetOption
(
TodoCommentOptions
.
TokenList
);
var
optionValue
=
_globalOptionService
.
GetOption
(
TodoCommentOptions
.
TokenList
);
if
(
optionValue
==
commentString
)
{
return
;
...
...
@@ -79,7 +78,7 @@ private void OnPropertyChanged(object sender, PropertyChangedEventArgs e)
_lastCommentTokenCache
=
commentString
;
// let people to know that comment string has changed
_
workspace
.
SetOptions
(
optionSet
.
WithChangedOption
(
TodoCommentOptions
.
TokenList
,
_lastCommentTokenCache
)
);
_
globalOptionService
.
RefreshOption
(
TodoCommentOptions
.
TokenList
,
_lastCommentTokenCache
);
}
private
static
string
GetTaskTokenList
(
ITaskList
taskList
)
...
...
src/VisualStudio/Core/Def/RoslynPackage.cs
浏览文件 @
ee2f9864
...
...
@@ -75,12 +75,12 @@ protected override async Task InitializeAsync(CancellationToken cancellationToke
var
method
=
compilerFailFast
.
GetMethod
(
nameof
(
FailFast
.
OnFatalException
),
BindingFlags
.
Static
|
BindingFlags
.
NonPublic
);
property
.
SetValue
(
null
,
Delegate
.
CreateDelegate
(
property
.
PropertyType
,
method
));
_workspace
=
_componentModel
.
GetService
<
VisualStudioWorkspace
>();
_workspace
.
Services
.
GetService
<
IExperimentationService
>();
// Ensure the options persisters are loaded since we have to fetch options from the shell
_componentModel
.
GetExtensions
<
IOptionPersister
>();
_workspace
=
_componentModel
.
GetService
<
VisualStudioWorkspace
>();
_workspace
.
Services
.
GetService
<
IExperimentationService
>();
RoslynTelemetrySetup
.
Initialize
(
this
);
InitializeColors
();
...
...
src/Workspaces/CSharp/Portable/Classification/SyntaxClassification/SyntaxTokenClassifier.cs
浏览文件 @
ee2f9864
...
...
@@ -71,13 +71,11 @@ private bool CouldBeGenericType(SyntaxToken identifier)
return
false
;
}
if
(
identifierName
.
IsMemberAccessExpressionName
())
// ?.X.Identifier or ?.X.Y.Identifier is never a generic type.
if
(
identifierName
.
IsMemberAccessExpressionName
()
&&
identifier
.
Parent
.
IsParentKind
(
SyntaxKind
.
ConditionalAccessExpression
))
{
// ?.X.Identifier or ?.X.Y.Identifier is never a generic type.
if
(
identifier
.
Parent
.
IsParentKind
(
SyntaxKind
.
ConditionalAccessExpression
))
{
return
false
;
}
return
false
;
}
// Add more cases as necessary.
...
...
src/Workspaces/CSharp/Portable/Extensions/DefaultExpressionSyntaxExtensions.cs
浏览文件 @
ee2f9864
...
...
@@ -35,9 +35,8 @@ internal static class DefaultExpressionSyntaxExtensions
private
static
bool
?
CanReplaceWithDefaultLiteralFast
(
DefaultExpressionSyntax
defaultExpression
,
SemanticModel
semanticModel
,
CancellationToken
cancellationToken
)
{
if
(
defaultExpression
.
IsParentKind
(
SyntaxKind
.
EqualsValueClause
))
if
(
defaultExpression
.
IsParentKind
(
SyntaxKind
.
EqualsValueClause
,
out
EqualsValueClauseSyntax
equalsValueClause
))
{
var
equalsValueClause
=
(
EqualsValueClauseSyntax
)
defaultExpression
.
Parent
;
var
typeSyntax
=
GetTypeSyntax
(
equalsValueClause
);
if
(
typeSyntax
!=
null
)
...
...
@@ -66,14 +65,12 @@ internal static class DefaultExpressionSyntaxExtensions
private
static
TypeSyntax
GetTypeSyntax
(
EqualsValueClauseSyntax
equalsValueClause
)
{
if
(
equalsValueClause
.
IsParentKind
(
SyntaxKind
.
VariableDeclarator
)
&&
equalsValueClause
.
Parent
.
IsParentKind
(
SyntaxKind
.
VariableDeclaration
))
equalsValueClause
.
Parent
.
IsParentKind
(
SyntaxKind
.
VariableDeclaration
,
out
VariableDeclarationSyntax
declaration
))
{
var
declaration
=
(
VariableDeclarationSyntax
)
equalsValueClause
.
Parent
.
Parent
;
return
declaration
.
Type
;
}
else
if
(
equalsValueClause
.
IsParentKind
(
SyntaxKind
.
Parameter
))
else
if
(
equalsValueClause
.
IsParentKind
(
SyntaxKind
.
Parameter
,
out
ParameterSyntax
parameter
))
{
var
parameter
=
(
ParameterSyntax
)
equalsValueClause
.
Parent
;
return
parameter
.
Type
;
}
...
...
src/Workspaces/CSharp/Portable/Rename/CSharpRenameRewriterLanguageService.cs
浏览文件 @
ee2f9864
...
...
@@ -299,30 +299,14 @@ private bool IsExpandWithinMultiLineLambda(SyntaxNode node)
return
true
;
}
if
(
node
.
IsParentKind
(
SyntaxKind
.
ParenthesizedLambdaExpression
))
if
(
node
.
IsParentKind
(
SyntaxKind
.
ParenthesizedLambdaExpression
,
out
ParenthesizedLambdaExpressionSyntax
parenLambda
))
{
var
parent
=
(
ParenthesizedLambdaExpressionSyntax
)
node
;
if
(
ReferenceEquals
(
parent
.
ParameterList
,
node
))
{
return
true
;
}
else
{
return
false
;
}
return
ReferenceEquals
(
parenLambda
.
ParameterList
,
node
);
}
if
(
node
.
IsParentKind
(
SyntaxKind
.
SimpleLambdaExpression
))
if
(
node
.
IsParentKind
(
SyntaxKind
.
SimpleLambdaExpression
,
out
SimpleLambdaExpressionSyntax
simpleLambda
))
{
var
parent
=
(
SimpleLambdaExpressionSyntax
)
node
;
if
(
ReferenceEquals
(
parent
.
Parameter
,
node
))
{
return
true
;
}
else
{
return
false
;
}
return
ReferenceEquals
(
simpleLambda
.
Parameter
,
node
);
}
return
true
;
...
...
src/Workspaces/CSharp/Portable/Simplification/CSharpSimplificationService.Expander.cs
浏览文件 @
ee2f9864
...
...
@@ -84,9 +84,8 @@ private bool IsPassedToDelegateCreationExpression(ArgumentSyntax argument, IType
{
if
(
type
.
IsDelegateType
()
&&
argument
.
IsParentKind
(
SyntaxKind
.
ArgumentList
)
&&
argument
.
Parent
.
IsParentKind
(
SyntaxKind
.
ObjectCreationExpression
))
argument
.
Parent
.
IsParentKind
(
SyntaxKind
.
ObjectCreationExpression
,
out
ObjectCreationExpressionSyntax
objectCreationExpression
))
{
var
objectCreationExpression
=
(
ObjectCreationExpressionSyntax
)
argument
.
Parent
.
Parent
;
var
objectCreationType
=
_semanticModel
.
GetTypeInfo
(
objectCreationExpression
).
Type
;
if
(
objectCreationType
.
Equals
(
type
))
{
...
...
src/Workspaces/CSharp/Portable/Simplification/Simplifiers/ExpressionSimplifier.cs
浏览文件 @
ee2f9864
...
...
@@ -482,9 +482,9 @@ private static bool IsThisOrTypeOrNamespace(MemberAccessExpressionSyntax memberA
var
symbol
=
semanticModel
.
GetSymbolInfo
(
memberAccess
.
Name
).
Symbol
;
if
(
previousToken
.
Kind
()
==
SyntaxKind
.
OpenParenToken
&&
previousToken
.
Parent
.
IsKind
(
SyntaxKind
.
ParenthesizedExpression
)
&&
previousToken
.
Parent
.
IsKind
(
SyntaxKind
.
ParenthesizedExpression
,
out
ParenthesizedExpressionSyntax
parenExpr
)
&&
!
previousToken
.
Parent
.
IsParentKind
(
SyntaxKind
.
ParenthesizedExpression
)
&&
((
ParenthesizedExpressionSyntax
)
previousToken
.
Parent
)
.
Expression
.
Kind
()
==
SyntaxKind
.
SimpleMemberAccessExpression
&&
parenExpr
.
Expression
.
Kind
()
==
SyntaxKind
.
SimpleMemberAccessExpression
&&
symbol
!=
null
&&
symbol
.
Kind
==
SymbolKind
.
Method
)
{
return
false
;
...
...
src/Workspaces/CSharp/Portable/Simplification/Simplifiers/NameSimplifier.cs
浏览文件 @
ee2f9864
...
...
@@ -641,18 +641,15 @@ private static bool IsAmbiguousCast(ExpressionSyntax expression, ExpressionSynta
// Can't simplify a type name in a cast expression if it would then cause the cast to be
// parsed differently. For example: (Goo::Bar)+1 is a cast. But if that simplifies to
// (Bar)+1 then that's an arithmetic expression.
if
(
expression
.
IsParentKind
(
SyntaxKind
.
CastExpression
))
if
(
expression
.
IsParentKind
(
SyntaxKind
.
CastExpression
,
out
CastExpressionSyntax
castExpression
)
&&
castExpression
.
Type
==
expression
)
{
var
castExpression
=
(
CastExpressionSyntax
)
expression
.
Parent
;
if
(
castExpression
.
Type
==
expression
)
{
var
newCastExpression
=
castExpression
.
ReplaceNode
(
castExpression
.
Type
,
simplifiedNode
);
var
reparsedCastExpression
=
SyntaxFactory
.
ParseExpression
(
newCastExpression
.
ToString
());
var
newCastExpression
=
castExpression
.
ReplaceNode
(
castExpression
.
Type
,
simplifiedNode
);
var
reparsedCastExpression
=
SyntaxFactory
.
ParseExpression
(
newCastExpression
.
ToString
());
if
(!
reparsedCastExpression
.
IsKind
(
SyntaxKind
.
CastExpression
))
{
return
true
;
}
if
(!
reparsedCastExpression
.
IsKind
(
SyntaxKind
.
CastExpression
))
{
return
true
;
}
}
...
...
@@ -674,8 +671,8 @@ private static bool IsQualifiedNameInUsingDirective(SemanticModel model, NameSyn
name
=
(
NameSyntax
)
name
.
Parent
;
}
if
(
name
.
IsParentKind
(
SyntaxKind
.
UsingDirective
)
&&
((
UsingDirectiveSyntax
)
name
.
Parent
)
.
Alias
==
null
)
if
(
name
.
IsParentKind
(
SyntaxKind
.
UsingDirective
,
out
UsingDirectiveSyntax
usingDirective
)
&&
usingDirective
.
Alias
==
null
)
{
// We're a qualified name in a using. We don't want to reduce this name as people like
// fully qualified names in usings so they can properly tell what the name is resolving
...
...
src/Workspaces/Core/Portable/Options/EditorConfig/EditorConfigDocumentOptionsProviderFactory.cs
浏览文件 @
ee2f9864
...
...
@@ -6,7 +6,6 @@
using
System
;
using
System.Collections.Immutable
;
using
System.Composition
;
using
System.Linq
;
using
System.Threading
;
using
System.Threading.Tasks
;
...
...
@@ -15,24 +14,11 @@
namespace
Microsoft.CodeAnalysis.Options.EditorConfig
{
[
Export
(
typeof
(
IDocumentOptionsProviderFactory
)),
Shared
]
[
ExportMetadata
(
"Name"
,
PredefinedDocumentOptionsProviderNames
.
EditorConfig
)]
internal
sealed
class
EditorConfigDocumentOptionsProviderFactory
:
IDocumentOptionsProviderFactory
internal
static
class
EditorConfigDocumentOptionsProviderFactory
{
[
ImportingConstructor
]
public
EditorConfigDocumentOptionsProviderFactory
()
public
static
IDocumentOptionsProvider
Create
(
Workspace
workspace
)
{
}
public
IDocumentOptionsProvider
?
TryCreate
(
Workspace
workspace
)
{
if
(!
ShouldUseNativeEditorConfigSupport
(
workspace
))
{
// Simply disable if the feature isn't on
return
null
;
}
return
new
EditorConfigDocumentOptionsProvider
(
workspace
.
Services
.
GetRequiredService
<
IErrorLoggerService
>());
return
new
EditorConfigDocumentOptionsProvider
(
workspace
.
Services
.
GetService
<
IErrorLoggerService
>());
}
private
const
string
LocalRegistryPath
=
@"Roslyn\Internal\OnOff\Features\"
;
...
...
@@ -48,15 +34,21 @@ public static bool ShouldUseNativeEditorConfigSupport(Workspace workspace)
private
class
EditorConfigDocumentOptionsProvider
:
IDocumentOptionsProvider
{
private
readonly
IErrorLoggerService
_errorLogger
;
private
readonly
IErrorLoggerService
?
_errorLogger
;
public
EditorConfigDocumentOptionsProvider
(
IErrorLoggerService
errorLogger
)
public
EditorConfigDocumentOptionsProvider
(
IErrorLoggerService
?
errorLogger
)
{
_errorLogger
=
errorLogger
;
}
public
async
Task
<
IDocumentOptions
?>
GetOptionsForDocumentAsync
(
Document
document
,
CancellationToken
cancellationToken
)
{
if
(!
ShouldUseNativeEditorConfigSupport
(
document
.
Project
.
Solution
.
Workspace
))
{
// Simply disable if the feature isn't on
return
null
;
}
var
options
=
await
document
.
GetAnalyzerOptionsAsync
(
cancellationToken
).
ConfigureAwait
(
false
);
return
new
DocumentOptions
(
options
,
_errorLogger
);
...
...
@@ -65,9 +57,9 @@ public EditorConfigDocumentOptionsProvider(IErrorLoggerService errorLogger)
private
class
DocumentOptions
:
IDocumentOptions
{
private
readonly
ImmutableDictionary
<
string
,
string
>
_options
;
private
readonly
IErrorLoggerService
_errorLogger
;
private
readonly
IErrorLoggerService
?
_errorLogger
;
public
DocumentOptions
(
ImmutableDictionary
<
string
,
string
>
options
,
IErrorLoggerService
errorLogger
)
public
DocumentOptions
(
ImmutableDictionary
<
string
,
string
>
options
,
IErrorLoggerService
?
errorLogger
)
{
_options
=
options
;
_errorLogger
=
errorLogger
;
...
...
src/Workspaces/Core/Portable/Workspace/Workspace.cs
浏览文件 @
ee2f9864
...
...
@@ -14,9 +14,11 @@
using
System.Threading.Tasks
;
using
Microsoft.CodeAnalysis
;
using
Microsoft.CodeAnalysis.Diagnostics
;
using
Microsoft.CodeAnalysis.ErrorLogger
;
using
Microsoft.CodeAnalysis.Host
;
using
Microsoft.CodeAnalysis.Internal.Log
;
using
Microsoft.CodeAnalysis.Options
;
using
Microsoft.CodeAnalysis.Options.EditorConfig
;
using
Microsoft.CodeAnalysis.Shared.Extensions
;
using
Microsoft.CodeAnalysis.Shared.Utilities
;
using
Microsoft.CodeAnalysis.Text
;
...
...
@@ -87,6 +89,8 @@ protected Workspace(HostServices host, string? workspaceKind)
var
info
=
SolutionInfo
.
Create
(
SolutionId
.
CreateNewId
(),
VersionStamp
.
Create
());
var
emptyOptions
=
new
SerializableOptionSet
(
languages
:
ImmutableHashSet
<
string
>.
Empty
,
_optionService
,
serializableOptions
:
ImmutableHashSet
<
IOption
>.
Empty
,
values
:
ImmutableDictionary
<
OptionKey
,
object
?>.
Empty
);
_latestSolution
=
CreateSolution
(
info
,
emptyOptions
);
_optionService
.
RegisterDocumentOptionsProvider
(
EditorConfigDocumentOptionsProviderFactory
.
Create
(
this
));
}
internal
void
LogTestMessage
(
string
message
)
...
...
src/Workspaces/SharedUtilitiesAndExtensions/Compiler/CSharp/Extensions/ExpressionSyntaxExtensions.cs
浏览文件 @
ee2f9864
...
...
@@ -18,10 +18,8 @@ internal static partial class ExpressionSyntaxExtensions
{
public
static
ExpressionSyntax
WalkUpParentheses
(
this
ExpressionSyntax
expression
)
{
while
(
expression
.
IsParentKind
(
SyntaxKind
.
ParenthesizedExpression
))
{
expression
=
(
ExpressionSyntax
)
expression
.
Parent
;
}
while
(
expression
.
IsParentKind
(
SyntaxKind
.
ParenthesizedExpression
,
out
ExpressionSyntax
parentExpr
))
expression
=
parentExpr
;
return
expression
;
}
...
...
@@ -42,10 +40,8 @@ public static bool IsQualifiedCrefName(this ExpressionSyntax expression)
}
public
static
bool
IsMemberAccessExpressionName
(
this
ExpressionSyntax
expression
)
{
return
(
expression
.
IsParentKind
(
SyntaxKind
.
SimpleMemberAccessExpression
)
&&
((
MemberAccessExpressionSyntax
)
expression
.
Parent
).
Name
==
expression
)
||
IsMemberBindingExpressionName
(
expression
);
}
=>
(
expression
.
IsParentKind
(
SyntaxKind
.
SimpleMemberAccessExpression
,
out
MemberAccessExpressionSyntax
memberAccess
)
&&
memberAccess
.
Name
==
expression
)
||
IsMemberBindingExpressionName
(
expression
);
public
static
bool
IsAnyMemberAccessExpressionName
(
this
ExpressionSyntax
expression
)
{
...
...
@@ -59,20 +55,14 @@ public static bool IsAnyMemberAccessExpressionName(this ExpressionSyntax express
}
private
static
bool
IsMemberBindingExpressionName
(
this
ExpressionSyntax
expression
)
{
return
expression
.
IsParentKind
(
SyntaxKind
.
MemberBindingExpression
)
&&
((
MemberBindingExpressionSyntax
)
expression
.
Parent
).
Name
==
expression
;
}
=>
expression
.
IsParentKind
(
SyntaxKind
.
MemberBindingExpression
,
out
MemberBindingExpressionSyntax
memberBinding
)
&&
memberBinding
.
Name
==
expression
;
public
static
bool
IsRightSideOfQualifiedName
(
this
ExpressionSyntax
expression
)
{
return
expression
.
IsParentKind
(
SyntaxKind
.
QualifiedName
)
&&
((
QualifiedNameSyntax
)
expression
.
Parent
).
Right
==
expression
;
}
=>
expression
.
IsParentKind
(
SyntaxKind
.
QualifiedName
,
out
QualifiedNameSyntax
qualifiedName
)
&&
qualifiedName
.
Right
==
expression
;
public
static
bool
IsRightSideOfColonColon
(
this
ExpressionSyntax
expression
)
{
return
expression
.
IsParentKind
(
SyntaxKind
.
AliasQualifiedName
)
&&
((
AliasQualifiedNameSyntax
)
expression
.
Parent
).
Name
==
expression
;
}
=>
expression
.
IsParentKind
(
SyntaxKind
.
AliasQualifiedName
,
out
AliasQualifiedNameSyntax
aliasName
)
&&
aliasName
.
Name
==
expression
;
public
static
bool
IsRightSideOfDot
(
this
ExpressionSyntax
name
)
{
...
...
@@ -127,7 +117,7 @@ public static bool IsLeftSideOfExplicitInterfaceSpecifier(this NameSyntax name)
=>
name
.
IsParentKind
(
SyntaxKind
.
ExplicitInterfaceSpecifier
);
public
static
bool
IsExpressionOfInvocation
(
this
ExpressionSyntax
expression
)
=>
(
expression
?.
Parent
).
Is
Kind
(
SyntaxKind
.
InvocationExpression
,
out
InvocationExpressionSyntax
invocation
)
&&
=>
expression
.
IsParent
Kind
(
SyntaxKind
.
InvocationExpression
,
out
InvocationExpressionSyntax
invocation
)
&&
invocation
.
Expression
==
expression
;
public
static
bool
TryGetNameParts
(
this
ExpressionSyntax
expression
,
out
IList
<
string
>
parts
)
...
...
src/Workspaces/SharedUtilitiesAndExtensions/Compiler/CSharp/Extensions/SimpleNameSyntaxExtensions.cs
浏览文件 @
ee2f9864
...
...
@@ -52,15 +52,15 @@ public static bool LooksLikeStandaloneTypeName(this SimpleNameSyntax simpleName)
}
// type names can't be invoked.
if
(
simpleName
.
IsParentKind
(
SyntaxKind
.
InvocationExpression
)
&&
((
InvocationExpressionSyntax
)
simpleName
.
Parent
)
.
Expression
==
simpleName
)
if
(
simpleName
.
IsParentKind
(
SyntaxKind
.
InvocationExpression
,
out
InvocationExpressionSyntax
invocation
)
&&
invocation
.
Expression
==
simpleName
)
{
return
false
;
}
// type names can't be indexed into.
if
(
simpleName
.
IsParentKind
(
SyntaxKind
.
ElementAccessExpression
)
&&
((
ElementAccessExpressionSyntax
)
simpleName
.
Parent
)
.
Expression
==
simpleName
)
if
(
simpleName
.
IsParentKind
(
SyntaxKind
.
ElementAccessExpression
,
out
ElementAccessExpressionSyntax
elementAccess
)
&&
elementAccess
.
Expression
==
simpleName
)
{
return
false
;
}
...
...
src/Workspaces/SharedUtilitiesAndExtensions/Compiler/CSharp/Extensions/SyntaxNodeExtensions.cs
浏览文件 @
ee2f9864
...
...
@@ -43,6 +43,19 @@ public static bool IsKind<TNode>([NotNullWhen(returnValue: true)] this SyntaxNod
public
static
bool
IsParentKind
([
NotNullWhen
(
returnValue
:
true
)]
this
SyntaxNode
?
node
,
SyntaxKind
kind
)
=>
CodeAnalysis
.
CSharpExtensions
.
IsKind
(
node
?.
Parent
,
kind
);
public
static
bool
IsParentKind
<
TNode
>([
NotNullWhen
(
returnValue
:
true
)]
this
SyntaxNode
?
node
,
SyntaxKind
kind
,
[
NotNullWhen
(
returnValue
:
true
)]
out
TNode
?
result
)
where
TNode
:
SyntaxNode
{
if
(
node
.
IsParentKind
(
kind
))
{
result
=
(
TNode
)
node
.
Parent
!;
return
true
;
}
result
=
null
;
return
false
;
}
public
static
bool
IsParentKind
([
NotNullWhen
(
returnValue
:
true
)]
this
SyntaxNode
?
node
,
SyntaxKind
kind1
,
SyntaxKind
kind2
)
=>
IsKind
(
node
?.
Parent
,
kind1
,
kind2
);
...
...
@@ -255,10 +268,10 @@ public static SyntaxList<AttributeListSyntax> GetAttributeLists(this SyntaxNode
var
current
=
node
;
while
(
current
?.
Parent
!=
null
)
{
if
(
current
.
IsParentKind
(
SyntaxKind
.
ConditionalAccessExpression
)
&&
((
ConditionalAccessExpressionSyntax
)
current
.
Parent
)
.
WhenNotNull
==
current
)
if
(
current
.
IsParentKind
(
SyntaxKind
.
ConditionalAccessExpression
,
out
ConditionalAccessExpressionSyntax
?
conditional
)
&&
conditional
.
WhenNotNull
==
current
)
{
return
(
ConditionalAccessExpressionSyntax
)
current
.
Parent
;
return
conditional
;
}
current
=
current
.
Parent
;
...
...
@@ -325,10 +338,8 @@ public static bool IsCompoundAssignExpression(this SyntaxNode node)
}
public
static
bool
IsLeftSideOfAssignExpression
([
NotNullWhen
(
returnValue
:
true
)]
this
SyntaxNode
?
node
)
{
return
node
.
IsParentKind
(
SyntaxKind
.
SimpleAssignmentExpression
)
&&
((
AssignmentExpressionSyntax
)
node
.
Parent
!).
Left
==
node
;
}
=>
node
.
IsParentKind
(
SyntaxKind
.
SimpleAssignmentExpression
,
out
AssignmentExpressionSyntax
?
assignment
)
&&
assignment
.
Left
==
node
;
public
static
bool
IsLeftSideOfAnyAssignExpression
(
this
SyntaxNode
node
)
{
...
...
@@ -728,12 +739,9 @@ public static bool ContainsInterleavedDirective(this SyntaxNode syntaxNode, Text
=>
CSharpSyntaxFacts
.
Instance
.
GetNodeWithoutLeadingBannerAndPreprocessorDirectives
(
node
,
out
strippedTrivia
);
public
static
bool
IsVariableDeclaratorValue
(
this
SyntaxNode
node
)
{
return
node
.
IsParentKind
(
SyntaxKind
.
EqualsValueClause
)
&&
node
.
Parent
.
IsParentKind
(
SyntaxKind
.
VariableDeclarator
)
&&
((
EqualsValueClauseSyntax
)
node
.
Parent
).
Value
==
node
;
}
=>
node
.
IsParentKind
(
SyntaxKind
.
EqualsValueClause
,
out
EqualsValueClauseSyntax
?
equalsValue
)
&&
equalsValue
.
IsParentKind
(
SyntaxKind
.
VariableDeclarator
)
&&
equalsValue
.
Value
==
node
;
public
static
BlockSyntax
?
FindInnermostCommonBlock
(
this
IEnumerable
<
SyntaxNode
>
nodes
)
{
...
...
src/Workspaces/SharedUtilitiesAndExtensions/Compiler/CSharp/Services/SyntaxFacts/CSharpSyntaxFacts.cs
浏览文件 @
ee2f9864
...
...
@@ -127,10 +127,8 @@ public bool IsNameOfMemberAccessExpression([NotNullWhen(true)] SyntaxNode? node)
#
nullable
restore
public
bool
IsObjectCreationExpressionType
(
SyntaxNode
node
)
{
return
node
.
IsParentKind
(
SyntaxKind
.
ObjectCreationExpression
)
&&
((
ObjectCreationExpressionSyntax
)
node
.
Parent
).
Type
==
node
;
}
=>
node
.
IsParentKind
(
SyntaxKind
.
ObjectCreationExpression
,
out
ObjectCreationExpressionSyntax
objectCreation
)
&&
objectCreation
.
Type
==
node
;
public
bool
IsAttributeName
(
SyntaxNode
node
)
{
...
...
@@ -164,11 +162,8 @@ public SyntaxToken GetIdentifierOfGenericName(SyntaxNode genericName)
}
public
bool
IsUsingDirectiveName
(
SyntaxNode
node
)
{
return
node
.
IsParentKind
(
SyntaxKind
.
UsingDirective
)
&&
((
UsingDirectiveSyntax
)
node
.
Parent
).
Name
==
node
;
}
=>
node
.
IsParentKind
(
SyntaxKind
.
UsingDirective
,
out
UsingDirectiveSyntax
usingDirective
)
&&
usingDirective
.
Name
==
node
;
public
bool
IsUsingAliasDirective
(
SyntaxNode
node
)
=>
node
is
UsingDirectiveSyntax
usingDirectiveNode
&&
usingDirectiveNode
.
Alias
!=
null
;
...
...
@@ -436,13 +431,13 @@ public bool IsTypeNamedVarInVariableOrFieldDeclaration(SyntaxToken token, Syntax
if
(
typedParent
.
IsKind
(
SyntaxKind
.
IdentifierName
))
{
TypeSyntax
declaredType
=
null
;
if
(
typedParent
.
IsParentKind
(
SyntaxKind
.
VariableDeclaration
))
if
(
typedParent
.
IsParentKind
(
SyntaxKind
.
VariableDeclaration
,
out
VariableDeclarationSyntax
varDecl
))
{
declaredType
=
((
VariableDeclarationSyntax
)
typedParent
.
Parent
)
.
Type
;
declaredType
=
varDecl
.
Type
;
}
else
if
(
typedParent
.
IsParentKind
(
SyntaxKind
.
FieldDeclaration
))
else
if
(
typedParent
.
IsParentKind
(
SyntaxKind
.
FieldDeclaration
,
out
FieldDeclarationSyntax
fieldDecl
))
{
declaredType
=
((
FieldDeclarationSyntax
)
typedParent
.
Parent
)
.
Declaration
.
Type
;
declaredType
=
fieldDecl
.
Declaration
.
Type
;
}
return
declaredType
==
typedParent
&&
typedToken
.
ValueText
==
"var"
;
...
...
@@ -643,9 +638,9 @@ public bool IsObjectInitializerNamedAssignmentIdentifier(SyntaxNode node)
initializedInstance
=
objectInitializer
.
Parent
;
return
true
;
}
else
if
(
objectInitializer
.
IsParentKind
(
SyntaxKind
.
SimpleAssignmentExpression
))
else
if
(
objectInitializer
.
IsParentKind
(
SyntaxKind
.
SimpleAssignmentExpression
,
out
AssignmentExpressionSyntax
assignment
))
{
initializedInstance
=
((
AssignmentExpressionSyntax
)
objectInitializer
.
Parent
)
.
Left
;
initializedInstance
=
assignment
.
Left
;
return
true
;
}
}
...
...
@@ -1217,22 +1212,16 @@ public SyntaxNode GetRightHandSideOfAssignment(SyntaxNode node)
=>
(
node
as
AssignmentExpressionSyntax
)?.
Right
;
public
bool
IsInferredAnonymousObjectMemberDeclarator
(
SyntaxNode
node
)
{
return
node
.
IsKind
(
SyntaxKind
.
AnonymousObjectMemberDeclarator
)
&&
((
AnonymousObjectMemberDeclaratorSyntax
)
node
).
NameEquals
==
null
;
}
=>
node
.
IsKind
(
SyntaxKind
.
AnonymousObjectMemberDeclarator
,
out
AnonymousObjectMemberDeclaratorSyntax
anonObject
)
&&
anonObject
.
NameEquals
==
null
;
public
bool
IsOperandOfIncrementExpression
(
SyntaxNode
node
)
{
return
node
.
IsParentKind
(
SyntaxKind
.
PostIncrementExpression
)
||
node
.
IsParentKind
(
SyntaxKind
.
PreIncrementExpression
);
}
=>
node
.
IsParentKind
(
SyntaxKind
.
PostIncrementExpression
)
||
node
.
IsParentKind
(
SyntaxKind
.
PreIncrementExpression
);
public
bool
IsOperandOfDecrementExpression
(
SyntaxNode
node
)
{
return
node
.
IsParentKind
(
SyntaxKind
.
PostDecrementExpression
)
||
node
.
IsParentKind
(
SyntaxKind
.
PreDecrementExpression
);
}
=>
node
.
IsParentKind
(
SyntaxKind
.
PostDecrementExpression
)
||
node
.
IsParentKind
(
SyntaxKind
.
PreDecrementExpression
);
public
bool
IsOperandOfIncrementOrDecrementExpression
(
SyntaxNode
node
)
{
...
...
src/Workspaces/SharedUtilitiesAndExtensions/Compiler/CSharp/Utilities/TypeStyle/CSharpUseExplicitTypeHelper.cs
浏览文件 @
ee2f9864
...
...
@@ -73,13 +73,10 @@ protected override bool ShouldAnalyzeForEachStatement(ForEachStatementSyntax for
{
// var (x, y) = e;
// foreach (var (x, y) in e) ...
if
(
typeName
.
IsParentKind
(
SyntaxKind
.
DeclarationExpression
))
if
(
typeName
.
IsParentKind
(
SyntaxKind
.
DeclarationExpression
,
out
DeclarationExpressionSyntax
declExpression
)
&&
declExpression
.
Designation
.
IsKind
(
SyntaxKind
.
ParenthesizedVariableDesignation
))
{
var
parent
=
(
DeclarationExpressionSyntax
)
typeName
.
Parent
;
if
(
parent
.
Designation
.
IsKind
(
SyntaxKind
.
ParenthesizedVariableDesignation
))
{
return
true
;
}
return
true
;
}
// If it is currently not var, explicit typing exists, return.
...
...
src/Workspaces/SharedUtilitiesAndExtensions/Workspace/CSharp/Extensions/CastExpressionSyntaxExtensions.cs
浏览文件 @
ee2f9864
...
...
@@ -308,14 +308,14 @@ private static bool IsDynamicInvocation(ExpressionSyntax castExpression, Semanti
{
var
typeInfo
=
default
(
TypeInfo
);
if
(
castExpression
.
Parent
.
Parent
.
IsParentKind
(
SyntaxKind
.
InvocationExpression
))
if
(
castExpression
.
Parent
.
Parent
.
IsParentKind
(
SyntaxKind
.
InvocationExpression
,
out
InvocationExpressionSyntax
invocation
))
{
typeInfo
=
semanticModel
.
GetTypeInfo
(
(
InvocationExpressionSyntax
)
castExpression
.
Parent
.
Parent
.
Parent
,
cancellationToken
);
typeInfo
=
semanticModel
.
GetTypeInfo
(
invocation
,
cancellationToken
);
}
if
(
castExpression
.
Parent
.
Parent
.
IsParentKind
(
SyntaxKind
.
ElementAccessExpression
))
if
(
castExpression
.
Parent
.
Parent
.
IsParentKind
(
SyntaxKind
.
ElementAccessExpression
,
out
ElementAccessExpressionSyntax
elementAccess
))
{
typeInfo
=
semanticModel
.
GetTypeInfo
(
(
ElementAccessExpressionSyntax
)
castExpression
.
Parent
.
Parent
.
Parent
,
cancellationToken
);
typeInfo
=
semanticModel
.
GetTypeInfo
(
elementAccess
,
cancellationToken
);
}
if
(
typeInfo
.
Type
!=
null
&&
typeInfo
.
Type
.
Kind
==
SymbolKind
.
DynamicType
)
...
...
src/Workspaces/SharedUtilitiesAndExtensions/Workspace/CSharp/Extensions/ContextQuery/SyntaxTokenExtensions.cs
浏览文件 @
ee2f9864
...
...
@@ -610,16 +610,10 @@ private static bool IsGenericInterfaceOrDelegateTypeParameterList(SyntaxNode nod
{
if
(
node
.
IsKind
(
SyntaxKind
.
TypeParameterList
))
{
if
(
node
.
IsParentKind
(
SyntaxKind
.
InterfaceDeclaration
))
{
var
decl
=
node
.
Parent
as
TypeDeclarationSyntax
;
return
decl
.
TypeParameterList
==
node
;
}
else
if
(
node
.
IsParentKind
(
SyntaxKind
.
DelegateDeclaration
))
{
var
decl
=
node
.
Parent
as
DelegateDeclarationSyntax
;
return
decl
.
TypeParameterList
==
node
;
}
if
(
node
.
IsParentKind
(
SyntaxKind
.
InterfaceDeclaration
,
out
TypeDeclarationSyntax
typeDecl
))
return
typeDecl
.
TypeParameterList
==
node
;
else
if
(
node
.
IsParentKind
(
SyntaxKind
.
DelegateDeclaration
,
out
DelegateDeclarationSyntax
delegateDecl
))
return
delegateDecl
.
TypeParameterList
==
node
;
}
return
false
;
...
...
src/Workspaces/SharedUtilitiesAndExtensions/Workspace/CSharp/Extensions/ContextQuery/SyntaxTreeExtensions.cs
浏览文件 @
ee2f9864
...
...
@@ -955,12 +955,11 @@ public static bool IsDefaultExpressionContext(this SyntaxTree syntaxTree, int po
// Might be an incomplete conditional expression or an incomplete declaration of a method returning a nullable type.
// Bind T to see if it is a type. If it is we don't show signature help.
if
(
name
.
IsParentKind
(
SyntaxKind
.
LessThanExpression
)
&&
name
.
Parent
.
IsParentKind
(
SyntaxKind
.
ConditionalExpression
)
&&
name
.
Parent
.
IsParentKind
(
SyntaxKind
.
ConditionalExpression
,
out
ConditionalExpressionSyntax
conditional
)
&&
name
.
Parent
.
Parent
.
IsParentKind
(
SyntaxKind
.
ExpressionStatement
)
&&
name
.
Parent
.
Parent
.
Parent
.
IsParentKind
(
SyntaxKind
.
GlobalStatement
))
{
var
conditionOrType
=
semanticModelOpt
.
GetSymbolInfo
(
((
ConditionalExpressionSyntax
)
name
.
Parent
.
Parent
).
Condition
,
cancellationToken
);
var
conditionOrType
=
semanticModelOpt
.
GetSymbolInfo
(
conditional
.
Condition
,
cancellationToken
);
if
(
conditionOrType
.
GetBestOrAllSymbols
().
FirstOrDefault
()
!=
null
&&
conditionOrType
.
GetBestOrAllSymbols
().
FirstOrDefault
().
Kind
==
SymbolKind
.
NamedType
)
{
...
...
@@ -1016,10 +1015,9 @@ public static bool IsDefaultExpressionContext(this SyntaxTree syntaxTree, int po
if
(
token
.
IsKind
(
SyntaxKind
.
CloseBracketToken
)
&&
token
.
Parent
.
IsKind
(
SyntaxKind
.
AttributeList
)
&&
token
.
Parent
.
IsParentKind
(
SyntaxKind
.
Parameter
)
&&
token
.
Parent
.
IsParentKind
(
SyntaxKind
.
Parameter
,
out
ParameterSyntax
parameter
)
&&
token
.
Parent
.
Parent
.
Parent
.
IsDelegateOrConstructorOrLocalFunctionOrMethodOrOperatorParameterList
(
includeOperators
))
{
var
parameter
=
(
ParameterSyntax
)
token
.
Parent
.
Parent
;
var
parameterList
=
(
ParameterListSyntax
)
parameter
.
Parent
;
parameterIndex
=
parameterList
.
Parameters
.
IndexOf
(
parameter
);
...
...
@@ -1031,7 +1029,7 @@ public static bool IsDefaultExpressionContext(this SyntaxTree syntaxTree, int po
token
.
Parent
.
IsKind
(
SyntaxKind
.
Parameter
)
&&
token
.
Parent
.
Parent
.
IsDelegateOrConstructorOrLocalFunctionOrMethodOrOperatorParameterList
(
includeOperators
))
{
var
parameter
=
(
ParameterSyntax
)
token
.
Parent
;
parameter
=
(
ParameterSyntax
)
token
.
Parent
;
var
parameterList
=
(
ParameterListSyntax
)
parameter
.
Parent
;
parameterIndex
=
parameterList
.
Parameters
.
IndexOf
(
parameter
);
...
...
@@ -1323,9 +1321,8 @@ public static bool IsPossibleTupleOpenParenOrComma(this SyntaxToken possibleComm
// in script
if
(
possibleCommaOrParen
.
Parent
.
IsKind
(
SyntaxKind
.
ParameterList
)
&&
possibleCommaOrParen
.
Parent
.
IsParentKind
(
SyntaxKind
.
ParenthesizedLambdaExpression
))
possibleCommaOrParen
.
Parent
.
IsParentKind
(
SyntaxKind
.
ParenthesizedLambdaExpression
,
out
ParenthesizedLambdaExpressionSyntax
parenthesizedLambda
))
{
var
parenthesizedLambda
=
(
ParenthesizedLambdaExpressionSyntax
)
possibleCommaOrParen
.
Parent
.
Parent
;
if
(
parenthesizedLambda
.
ArrowToken
.
IsMissing
)
{
return
true
;
...
...
@@ -1434,11 +1431,10 @@ private static bool IsPossibleVarDeconstructionOpenParenOrComma(SyntaxToken left
{
if
(
leftToken
.
IsKind
(
SyntaxKind
.
OpenParenToken
,
SyntaxKind
.
CommaToken
)
&&
leftToken
.
Parent
.
IsKind
(
SyntaxKind
.
ArgumentList
)
&&
leftToken
.
Parent
.
IsParentKind
(
SyntaxKind
.
InvocationExpression
))
leftToken
.
Parent
.
IsParentKind
(
SyntaxKind
.
InvocationExpression
,
out
InvocationExpressionSyntax
invocation
))
{
var
invocation
=
(
InvocationExpressionSyntax
)
leftToken
.
Parent
.
Parent
;
if
(
invocation
.
Expression
.
IsKind
(
SyntaxKind
.
IdentifierName
)
&&
((
IdentifierNameSyntax
)
invocation
.
Expression
).
Identifier
.
ValueText
==
"var"
)
if
(
invocation
.
Expression
.
IsKind
(
SyntaxKind
.
IdentifierName
,
out
IdentifierNameSyntax
identifierName
)
&&
identifierName
.
Identifier
.
ValueText
==
"var"
)
{
return
true
;
}
...
...
@@ -2149,14 +2145,12 @@ public static bool IsLabelContext(this SyntaxTree syntaxTree, int position, Canc
{
var
type
=
previousToken
.
Parent
as
TypeSyntax
;
if
(
type
.
IsParentKind
(
SyntaxKind
.
VariableDeclaration
)
&&
type
.
Parent
.
IsParentKind
(
SyntaxKind
.
LocalDeclarationStatement
))
type
.
Parent
.
IsParentKind
(
SyntaxKind
.
LocalDeclarationStatement
,
out
LocalDeclarationStatementSyntax
declStatement
))
{
var
declStatement
=
type
.
Parent
.
Parent
as
LocalDeclarationStatementSyntax
;
// note, this doesn't apply for cases where we know it
// absolutely is not multiplication or a conditional expression.
var
underlyingType
=
type
is
PointerTypeSyntax
?
((
PointerTypeSyntax
)
type
)
.
ElementType
var
underlyingType
=
type
is
PointerTypeSyntax
pointerType
?
pointerType
.
ElementType
:
((
NullableTypeSyntax
)
type
).
ElementType
;
if
(!
underlyingType
.
IsPotentialTypeName
(
semanticModelOpt
,
cancellationToken
))
...
...
@@ -2309,9 +2303,8 @@ public static bool IsLabelContext(this SyntaxTree syntaxTree, int position, Canc
// can support a collection initializer. If not, this must be an object initializer
// and can't be an expression context.
if
(
semanticModelOpt
!=
null
&&
token
.
Parent
.
IsParentKind
(
SyntaxKind
.
ObjectCreationExpression
))
token
.
Parent
.
IsParentKind
(
SyntaxKind
.
ObjectCreationExpression
,
out
ObjectCreationExpressionSyntax
objectCreation
))
{
var
objectCreation
=
(
ObjectCreationExpressionSyntax
)
token
.
Parent
.
Parent
;
var
containingSymbol
=
semanticModelOpt
.
GetEnclosingNamedTypeOrAssembly
(
position
,
cancellationToken
);
if
(
semanticModelOpt
.
GetSymbolInfo
(
objectCreation
.
Type
,
cancellationToken
).
Symbol
is
ITypeSymbol
type
&&
!
type
.
CanSupportCollectionInitializer
(
containingSymbol
))
{
...
...
@@ -2681,8 +2674,8 @@ public static bool IsNameOfContext(this SyntaxTree syntaxTree, int position, Sem
if
(
CodeAnalysis
.
CSharpExtensions
.
IsKind
(
token
,
SyntaxKind
.
IdentifierToken
)
&&
token
.
Parent
.
IsKind
(
SyntaxKind
.
IdentifierName
))
{
if
(
token
.
Parent
.
IsParentKind
(
SyntaxKind
.
Argument
)
&&
CodeAnalysis
.
CSharpExtensions
.
IsKind
(((
ArgumentSyntax
)
token
.
Parent
.
Parent
).
RefOrOutKeyword
,
SyntaxKind
.
OutKeyword
))
if
(
token
.
Parent
.
IsParentKind
(
SyntaxKind
.
Argument
,
out
ArgumentSyntax
argument
)
&&
argument
.
RefOrOutKeyword
.
IsKind
(
SyntaxKind
.
OutKeyword
))
{
return
false
;
}
...
...
src/Workspaces/SharedUtilitiesAndExtensions/Workspace/CSharp/Extensions/ParenthesizedExpressionSyntaxExtensions.cs
浏览文件 @
ee2f9864
...
...
@@ -105,19 +105,19 @@ public static bool CanRemoveParentheses(this ParenthesizedExpressionSyntax node,
// lock ((x)) -> lock (x)
// using ((x)) -> using (x)
// catch when ((x)) -> catch when (x)
if
((
node
.
IsParentKind
(
SyntaxKind
.
EqualsValueClause
)
&&
((
EqualsValueClauseSyntax
)
node
.
Parent
)
.
Value
==
node
)
||
(
node
.
IsParentKind
(
SyntaxKind
.
IfStatement
)
&&
((
IfStatementSyntax
)
node
.
Parent
)
.
Condition
==
node
)
||
(
node
.
IsParentKind
(
SyntaxKind
.
ReturnStatement
)
&&
((
ReturnStatementSyntax
)
node
.
Parent
)
.
Expression
==
node
)
||
(
node
.
IsParentKind
(
SyntaxKind
.
YieldReturnStatement
)
&&
((
YieldStatementSyntax
)
node
.
Parent
)
.
Expression
==
node
)
||
(
node
.
IsParentKind
(
SyntaxKind
.
ThrowStatement
)
&&
((
ThrowStatementSyntax
)
node
.
Parent
)
.
Expression
==
node
)
||
(
node
.
IsParentKind
(
SyntaxKind
.
SwitchStatement
)
&&
((
SwitchStatementSyntax
)
node
.
Parent
)
.
Expression
==
node
)
||
(
node
.
IsParentKind
(
SyntaxKind
.
WhileStatement
)
&&
((
WhileStatementSyntax
)
node
.
Parent
)
.
Condition
==
node
)
||
(
node
.
IsParentKind
(
SyntaxKind
.
DoStatement
)
&&
((
DoStatementSyntax
)
node
.
Parent
)
.
Condition
==
node
)
||
(
node
.
IsParentKind
(
SyntaxKind
.
ForStatement
)
&&
((
ForStatementSyntax
)
node
.
Parent
)
.
Condition
==
node
)
||
if
((
node
.
IsParentKind
(
SyntaxKind
.
EqualsValueClause
,
out
EqualsValueClauseSyntax
equalsValue
)
&&
equalsValue
.
Value
==
node
)
||
(
node
.
IsParentKind
(
SyntaxKind
.
IfStatement
,
out
IfStatementSyntax
ifStatement
)
&&
ifStatement
.
Condition
==
node
)
||
(
node
.
IsParentKind
(
SyntaxKind
.
ReturnStatement
,
out
ReturnStatementSyntax
returnStatement
)
&&
returnStatement
.
Expression
==
node
)
||
(
node
.
IsParentKind
(
SyntaxKind
.
YieldReturnStatement
,
out
YieldStatementSyntax
yieldStatement
)
&&
yieldStatement
.
Expression
==
node
)
||
(
node
.
IsParentKind
(
SyntaxKind
.
ThrowStatement
,
out
ThrowStatementSyntax
throwStatement
)
&&
throwStatement
.
Expression
==
node
)
||
(
node
.
IsParentKind
(
SyntaxKind
.
SwitchStatement
,
out
SwitchStatementSyntax
switchStatement
)
&&
switchStatement
.
Expression
==
node
)
||
(
node
.
IsParentKind
(
SyntaxKind
.
WhileStatement
,
out
WhileStatementSyntax
whileStatement
)
&&
whileStatement
.
Condition
==
node
)
||
(
node
.
IsParentKind
(
SyntaxKind
.
DoStatement
,
out
DoStatementSyntax
doStatement
)
&&
doStatement
.
Condition
==
node
)
||
(
node
.
IsParentKind
(
SyntaxKind
.
ForStatement
,
out
ForStatementSyntax
forStatement
)
&&
forStatement
.
Condition
==
node
)
||
(
node
.
IsParentKind
(
SyntaxKind
.
ForEachStatement
,
SyntaxKind
.
ForEachVariableStatement
)
&&
((
CommonForEachStatementSyntax
)
node
.
Parent
).
Expression
==
node
)
||
(
node
.
IsParentKind
(
SyntaxKind
.
LockStatement
)
&&
((
LockStatementSyntax
)
node
.
Parent
)
.
Expression
==
node
)
||
(
node
.
IsParentKind
(
SyntaxKind
.
UsingStatement
)
&&
((
UsingStatementSyntax
)
node
.
Parent
)
.
Expression
==
node
)
||
(
node
.
IsParentKind
(
SyntaxKind
.
CatchFilterClause
)
&&
((
CatchFilterClauseSyntax
)
node
.
Parent
)
.
FilterExpression
==
node
))
(
node
.
IsParentKind
(
SyntaxKind
.
LockStatement
,
out
LockStatementSyntax
lockStatement
)
&&
lockStatement
.
Expression
==
node
)
||
(
node
.
IsParentKind
(
SyntaxKind
.
UsingStatement
,
out
UsingStatementSyntax
usingStatement
)
&&
usingStatement
.
Expression
==
node
)
||
(
node
.
IsParentKind
(
SyntaxKind
.
CatchFilterClause
,
out
CatchFilterClauseSyntax
catchFilter
)
&&
catchFilter
.
FilterExpression
==
node
))
{
return
true
;
}
...
...
@@ -139,7 +139,7 @@ public static bool CanRemoveParentheses(this ParenthesizedExpressionSyntax node,
// Cases:
// y((x)) -> y(x)
if
(
node
.
IsParentKind
(
SyntaxKind
.
Argument
)
&&
((
ArgumentSyntax
)
node
.
Parent
)
.
Expression
==
node
)
if
(
node
.
IsParentKind
(
SyntaxKind
.
Argument
,
out
ArgumentSyntax
argument
)
&&
argument
.
Expression
==
node
)
{
return
true
;
}
...
...
@@ -213,10 +213,16 @@ public static bool CanRemoveParentheses(this ParenthesizedExpressionSyntax node,
return
true
;
}
// (this) -> this
if
(
expression
.
IsKind
(
SyntaxKind
.
ThisExpression
))
{
return
true
;
}
// x ?? (throw ...) -> x ?? throw ...
if
(
expression
.
IsKind
(
SyntaxKind
.
ThrowExpression
)
&&
node
.
IsParentKind
(
SyntaxKind
.
CoalesceExpression
)
&&
((
BinaryExpressionSyntax
)
node
.
Parent
)
.
Right
==
node
)
node
.
IsParentKind
(
SyntaxKind
.
CoalesceExpression
,
out
BinaryExpressionSyntax
binary
)
&&
binary
.
Right
==
node
)
{
return
true
;
}
...
...
@@ -462,9 +468,8 @@ private static bool RemovalMayIntroduceCastAmbiguity(ParenthesizedExpressionSynt
// (X?)(...)
// (global::X)(...)
if
(
node
.
IsParentKind
(
SyntaxKind
.
CastExpression
))
if
(
node
.
IsParentKind
(
SyntaxKind
.
CastExpression
,
out
CastExpressionSyntax
castExpression
))
{
var
castExpression
=
(
CastExpressionSyntax
)
node
.
Parent
;
if
(
castExpression
.
Type
.
IsKind
(
SyntaxKind
.
PredefinedType
,
SyntaxKind
.
ArrayType
,
...
...
@@ -589,9 +594,8 @@ private static bool IsPreviousExpressionPotentiallyAmbiguous(ExpressionSyntax no
{
ExpressionSyntax
previousExpression
=
null
;
if
(
node
.
IsParentKind
(
SyntaxKind
.
Argument
))
if
(
node
.
IsParentKind
(
SyntaxKind
.
Argument
,
out
ArgumentSyntax
argument
))
{
var
argument
=
(
ArgumentSyntax
)
node
.
Parent
;
if
(
argument
.
Parent
is
ArgumentListSyntax
argumentList
)
{
var
argumentIndex
=
argumentList
.
Arguments
.
IndexOf
(
argument
);
...
...
@@ -627,9 +631,8 @@ private static bool IsNextExpressionPotentiallyAmbiguous(ExpressionSyntax node)
{
ExpressionSyntax
nextExpression
=
null
;
if
(
node
.
IsParentKind
(
SyntaxKind
.
Argument
))
if
(
node
.
IsParentKind
(
SyntaxKind
.
Argument
,
out
ArgumentSyntax
argument
))
{
var
argument
=
(
ArgumentSyntax
)
node
.
Parent
;
if
(
argument
.
Parent
is
ArgumentListSyntax
argumentList
)
{
var
argumentIndex
=
argumentList
.
Arguments
.
IndexOf
(
argument
);
...
...
src/Workspaces/SharedUtilitiesAndExtensions/Workspace/CSharp/Extensions/SemanticModelExtensions.cs
浏览文件 @
ee2f9864
...
...
@@ -262,9 +262,8 @@ private static bool CanBindToken(SyntaxToken token)
SemanticModel
semanticModel
,
ExpressionSyntax
expression
,
CancellationToken
cancellationToken
)
{
var
topExpression
=
expression
.
WalkUpParentheses
();
if
(
topExpression
.
IsParentKind
(
SyntaxKind
.
Argument
))
if
(
topExpression
.
IsParentKind
(
SyntaxKind
.
Argument
,
out
ArgumentSyntax
argument
))
{
var
argument
=
(
ArgumentSyntax
)
topExpression
.
Parent
;
if
(
argument
.
NameColon
!=
null
)
{
return
argument
.
NameColon
.
Name
.
Identifier
.
ValueText
;
...
...
@@ -332,14 +331,16 @@ public static ISet<INamespaceSymbol> GetUsingNamespacesInScope(this SemanticMode
// as the interface type itself.
if
(
type
!=
null
)
{
if
(
type
.
Parent
is
BaseTypeSyntax
&&
type
.
Parent
.
IsParentKind
(
SyntaxKind
.
BaseList
)
&&
((
BaseTypeSyntax
)
type
.
Parent
).
Type
==
type
)
if
(
type
.
Parent
is
BaseTypeSyntax
baseType
&&
type
.
Parent
.
IsParentKind
(
SyntaxKind
.
BaseList
,
out
BaseListSyntax
baseList
)
&&
baseType
.
Type
==
type
)
{
var
containingType
=
semanticModel
.
GetDeclaredSymbol
(
type
.
GetAncestor
<
BaseTypeDeclarationSyntax
>(),
cancellationToken
)
as
INamedTypeSymbol
;
if
(
containingType
!=
null
&&
containingType
.
TypeKind
==
TypeKind
.
Interface
)
{
return
containingType
.
DeclaredAccessibility
;
}
else
if
(
((
BaseListSyntax
)
type
.
Parent
.
Parent
)
.
Types
[
0
]
==
type
.
Parent
)
else
if
(
baseList
.
Types
[
0
]
==
type
.
Parent
)
{
return
containingType
.
DeclaredAccessibility
;
}
...
...
@@ -348,10 +349,9 @@ public static ISet<INamespaceSymbol> GetUsingNamespacesInScope(this SemanticMode
// 4) The type of a constant must be at least as accessible as the constant itself.
// 5) The type of a field must be at least as accessible as the field itself.
if
(
type
.
IsParentKind
(
SyntaxKind
.
VariableDeclaration
)
&&
if
(
type
.
IsParentKind
(
SyntaxKind
.
VariableDeclaration
,
out
VariableDeclarationSyntax
variableDeclaration
)
&&
type
.
Parent
.
IsParentKind
(
SyntaxKind
.
FieldDeclaration
))
{
var
variableDeclaration
=
(
VariableDeclarationSyntax
)
type
.
Parent
;
return
semanticModel
.
GetDeclaredSymbol
(
variableDeclaration
.
Variables
[
0
],
cancellationToken
).
DeclaredAccessibility
;
}
...
...
@@ -360,10 +360,9 @@ public static ISet<INamespaceSymbol> GetUsingNamespacesInScope(this SemanticMode
if
(
type
.
IsParentKind
(
SyntaxKind
.
ObjectCreationExpression
)
&&
type
.
Parent
.
IsParentKind
(
SyntaxKind
.
EqualsValueClause
)
&&
type
.
Parent
.
Parent
.
IsParentKind
(
SyntaxKind
.
VariableDeclarator
)
&&
type
.
Parent
.
Parent
.
Parent
.
IsParentKind
(
SyntaxKind
.
VariableDeclaration
)
&&
type
.
Parent
.
Parent
.
Parent
.
IsParentKind
(
SyntaxKind
.
VariableDeclaration
,
out
variableDeclaration
)
&&
type
.
Parent
.
Parent
.
Parent
.
Parent
.
IsParentKind
(
SyntaxKind
.
FieldDeclaration
))
{
var
variableDeclaration
=
(
VariableDeclarationSyntax
)
type
.
Parent
.
Parent
.
Parent
.
Parent
;
return
semanticModel
.
GetDeclaredSymbol
(
variableDeclaration
.
Variables
[
0
],
cancellationToken
).
DeclaredAccessibility
;
}
...
...
@@ -420,10 +419,9 @@ public static ISet<INamespaceSymbol> GetUsingNamespacesInScope(this SemanticMode
}
// 8) The type of an event must be at least as accessible as the event itself.
if
(
type
.
IsParentKind
(
SyntaxKind
.
VariableDeclaration
)
&&
if
(
type
.
IsParentKind
(
SyntaxKind
.
VariableDeclaration
,
out
variableDeclaration
)
&&
type
.
Parent
.
IsParentKind
(
SyntaxKind
.
EventFieldDeclaration
))
{
var
variableDeclaration
=
(
VariableDeclarationSyntax
)
type
.
Parent
;
var
symbol
=
semanticModel
.
GetDeclaredSymbol
(
variableDeclaration
.
Variables
[
0
],
cancellationToken
);
if
(
symbol
!=
null
)
{
...
...
src/Workspaces/SharedUtilitiesAndExtensions/Workspace/CSharp/LanguageServices/CSharpTypeInferenceService.TypeInferrer.cs
浏览文件 @
ee2f9864
...
...
@@ -239,6 +239,7 @@ protected override IEnumerable<TypeInferenceInfo> InferTypesWorker_DoNotCallDire
SwitchLabelSyntax
switchLabel
=>
InferTypeInSwitchLabel
(
switchLabel
,
token
),
SwitchStatementSyntax
switchStatement
=>
InferTypeInSwitchStatement
(
switchStatement
,
token
),
ThrowStatementSyntax
throwStatement
=>
InferTypeInThrowStatement
(
throwStatement
,
token
),
TupleExpressionSyntax
tupleExpression
=>
InferTypeInTupleExpression
(
tupleExpression
,
token
),
UsingStatementSyntax
usingStatement
=>
InferTypeInUsingStatement
(
usingStatement
,
token
),
WhenClauseSyntax
whenClause
=>
InferTypeInWhenClause
(
whenClause
,
token
),
WhileStatementSyntax
whileStatement
=>
InferTypeInWhileStatement
(
whileStatement
,
token
),
...
...
@@ -277,52 +278,45 @@ private IEnumerable<TypeInferenceInfo> InferTypeInAnonymousObjectCreation(Anonym
return
InferTypeInConstructorInitializer
(
initializer
,
index
,
argument
);
}
if
(
argument
.
Parent
.
IsParentKind
(
SyntaxKind
.
InvocationExpression
))
if
(
argument
.
Parent
.
IsParentKind
(
SyntaxKind
.
InvocationExpression
,
out
InvocationExpressionSyntax
invocation
))
{
var
invocation
=
argument
.
Parent
.
Parent
as
InvocationExpressionSyntax
;
var
index
=
invocation
.
ArgumentList
.
Arguments
.
IndexOf
(
argument
);
return
InferTypeInInvocationExpression
(
invocation
,
index
,
argument
);
}
if
(
argument
.
Parent
.
IsParentKind
(
SyntaxKind
.
ObjectCreationExpression
))
if
(
argument
.
Parent
.
IsParentKind
(
SyntaxKind
.
ObjectCreationExpression
,
out
ObjectCreationExpressionSyntax
creation
))
{
// new Outer(Goo());
//
// new Outer(a: Goo());
//
// etc.
var
creation
=
argument
.
Parent
.
Parent
as
ObjectCreationExpressionSyntax
;
var
index
=
creation
.
ArgumentList
.
Arguments
.
IndexOf
(
argument
);
return
InferTypeInObjectCreationExpression
(
creation
,
index
,
argument
);
}
if
(
argument
.
Parent
.
IsParentKind
(
SyntaxKind
.
ElementAccessExpression
))
if
(
argument
.
Parent
.
IsParentKind
(
SyntaxKind
.
ElementAccessExpression
,
out
ElementAccessExpressionSyntax
elementAccess
))
{
// Outer[Goo()];
//
// Outer[a: Goo()];
//
// etc.
var
elementAccess
=
argument
.
Parent
.
Parent
as
ElementAccessExpressionSyntax
;
var
index
=
elementAccess
.
ArgumentList
.
Arguments
.
IndexOf
(
argument
);
return
InferTypeInElementAccessExpression
(
elementAccess
,
index
,
argument
);
}
if
(
argument
.
IsParentKind
(
SyntaxKind
.
TupleExpression
))
if
(
argument
.
IsParentKind
(
SyntaxKind
.
TupleExpression
,
out
TupleExpressionSyntax
tupleExpression
))
{
return
InferTypeInTupleExpression
(
(
TupleExpressionSyntax
)
argument
.
Parent
,
argument
);
return
InferTypeInTupleExpression
(
tupleExpression
,
argument
);
}
}
if
(
argument
.
Parent
.
IsParentKind
(
SyntaxKind
.
ImplicitElementAccess
)
&&
argument
.
Parent
.
Parent
.
IsParentKind
(
SyntaxKind
.
SimpleAssignmentExpression
)
&&
argument
.
Parent
.
Parent
.
Parent
.
IsParentKind
(
SyntaxKind
.
ObjectInitializerExpression
)
&&
argument
.
Parent
.
Parent
.
Parent
.
Parent
.
IsParentKind
(
SyntaxKind
.
ObjectCreationExpression
))
argument
.
Parent
.
Parent
.
Parent
.
Parent
.
IsParentKind
(
SyntaxKind
.
ObjectCreationExpression
,
out
ObjectCreationExpressionSyntax
objectCreation
))
{
var
objectCreation
=
(
ObjectCreationExpressionSyntax
)
argument
.
Parent
.
Parent
.
Parent
.
Parent
.
Parent
;
var
types
=
GetTypes
(
objectCreation
).
Select
(
t
=>
t
.
InferredType
);
if
(
types
.
Any
(
t
=>
t
is
INamedTypeSymbol
))
...
...
@@ -335,6 +329,22 @@ private IEnumerable<TypeInferenceInfo> InferTypeInAnonymousObjectCreation(Anonym
return
SpecializedCollections
.
EmptyEnumerable
<
TypeInferenceInfo
>();
}
private
IEnumerable
<
TypeInferenceInfo
>
InferTypeInTupleExpression
(
TupleExpressionSyntax
tupleExpression
,
SyntaxToken
previousToken
)
{
if
(
previousToken
==
tupleExpression
.
OpenParenToken
)
return
InferTypeInTupleExpression
(
tupleExpression
,
tupleExpression
.
Arguments
[
0
]);
if
(
previousToken
.
IsKind
(
SyntaxKind
.
CommaToken
))
{
var
argsAndCommas
=
tupleExpression
.
Arguments
.
GetWithSeparators
();
var
commaIndex
=
argsAndCommas
.
IndexOf
(
previousToken
);
return
InferTypeInTupleExpression
(
tupleExpression
,
(
ArgumentSyntax
)
argsAndCommas
[
commaIndex
+
1
]);
}
return
SpecializedCollections
.
EmptyEnumerable
<
TypeInferenceInfo
>();
}
private
IEnumerable
<
TypeInferenceInfo
>
InferTypeInTupleExpression
(
TupleExpressionSyntax
tupleExpression
,
ArgumentSyntax
argument
)
{
...
...
@@ -1164,26 +1174,18 @@ private IEnumerable<TypeInferenceInfo> InferTypeInEqualsValueClause(EqualsValueC
{
// If we have a position, it has to be after the =
if
(
previousToken
.
HasValue
&&
previousToken
.
Value
!=
equalsValue
.
EqualsToken
)
{
return
SpecializedCollections
.
EmptyEnumerable
<
TypeInferenceInfo
>();
}
if
(
equalsValue
.
IsParentKind
(
SyntaxKind
.
VariableDeclarator
))
{
return
InferTypeInVariableDeclarator
((
VariableDeclaratorSyntax
)
equalsValue
.
Parent
);
}
if
(
equalsValue
.
IsParentKind
(
SyntaxKind
.
VariableDeclarator
,
out
VariableDeclaratorSyntax
varDecl
))
return
InferTypeInVariableDeclarator
(
varDecl
);
if
(
equalsValue
.
IsParentKind
(
SyntaxKind
.
PropertyDeclaration
))
{
return
InferTypeInPropertyDeclaration
((
PropertyDeclarationSyntax
)
equalsValue
.
Parent
);
}
if
(
equalsValue
.
IsParentKind
(
SyntaxKind
.
PropertyDeclaration
,
out
PropertyDeclarationSyntax
propertyDecl
))
return
InferTypeInPropertyDeclaration
(
propertyDecl
);
if
(
equalsValue
.
IsParentKind
(
SyntaxKind
.
Parameter
))
if
(
equalsValue
.
IsParentKind
(
SyntaxKind
.
Parameter
)
&&
SemanticModel
.
GetDeclaredSymbol
(
equalsValue
.
Parent
,
CancellationToken
)
is
IParameterSymbol
parameter
)
{
if
(
SemanticModel
.
GetDeclaredSymbol
(
equalsValue
.
Parent
,
CancellationToken
)
is
IParameterSymbol
parameter
)
{
return
CreateResult
(
parameter
.
Type
);
}
return
CreateResult
(
parameter
.
Type
);
}
return
SpecializedCollections
.
EmptyEnumerable
<
TypeInferenceInfo
>();
...
...
@@ -1326,7 +1328,7 @@ private IEnumerable<TypeInferenceInfo> InferTypeInImplicitArrayCreation(Implicit
}
}
if
(
initializerExpression
.
IsParentKind
(
SyntaxKind
.
ImplicitArrayCreationExpression
))
if
(
initializerExpression
.
IsParentKind
(
SyntaxKind
.
ImplicitArrayCreationExpression
,
out
ImplicitArrayCreationExpressionSyntax
implicitArray
))
{
// new[] { 1, x }
...
...
@@ -1334,7 +1336,7 @@ private IEnumerable<TypeInferenceInfo> InferTypeInImplicitArrayCreation(Implicit
// appropriate array type, then use the element type of the array. Otherwise,
// look at the siblings of this expression and use their type instead.
var
arrayTypes
=
this
.
InferTypes
(
(
ExpressionSyntax
)
initializerExpression
.
Parent
);
var
arrayTypes
=
this
.
InferTypes
(
implicitArray
);
var
elementTypes
=
arrayTypes
.
OfType
<
IArrayTypeSymbol
>().
Select
(
a
=>
new
TypeInferenceInfo
(
a
.
ElementType
)).
Where
(
IsUsableTypeFunc
);
if
(
elementTypes
.
Any
())
...
...
@@ -1354,10 +1356,9 @@ private IEnumerable<TypeInferenceInfo> InferTypeInImplicitArrayCreation(Implicit
}
}
}
else
if
(
initializerExpression
.
IsParentKind
(
SyntaxKind
.
EqualsValueClause
))
else
if
(
initializerExpression
.
IsParentKind
(
SyntaxKind
.
EqualsValueClause
,
out
EqualsValueClauseSyntax
equalsValueClause
))
{
// = { Goo() }
var
equalsValueClause
=
(
EqualsValueClauseSyntax
)
initializerExpression
.
Parent
;
var
types
=
InferTypeInEqualsValueClause
(
equalsValueClause
).
Select
(
t
=>
t
.
InferredType
);
if
(
types
.
Any
(
t
=>
t
is
IArrayTypeSymbol
))
...
...
@@ -1365,10 +1366,9 @@ private IEnumerable<TypeInferenceInfo> InferTypeInImplicitArrayCreation(Implicit
return
types
.
OfType
<
IArrayTypeSymbol
>().
Select
(
t
=>
new
TypeInferenceInfo
(
t
.
ElementType
));
}
}
else
if
(
initializerExpression
.
IsParentKind
(
SyntaxKind
.
ArrayCreationExpression
))
else
if
(
initializerExpression
.
IsParentKind
(
SyntaxKind
.
ArrayCreationExpression
,
out
ArrayCreationExpressionSyntax
arrayCreation
))
{
// new int[] { Goo() }
var
arrayCreation
=
(
ArrayCreationExpressionSyntax
)
initializerExpression
.
Parent
;
var
types
=
GetTypes
(
arrayCreation
).
Select
(
t
=>
t
.
InferredType
);
if
(
types
.
Any
(
t
=>
t
is
IArrayTypeSymbol
))
...
...
@@ -1376,12 +1376,9 @@ private IEnumerable<TypeInferenceInfo> InferTypeInImplicitArrayCreation(Implicit
return
types
.
OfType
<
IArrayTypeSymbol
>().
Select
(
t
=>
new
TypeInferenceInfo
(
t
.
ElementType
));
}
}
else
if
(
initializerExpression
.
IsParentKind
(
SyntaxKind
.
ObjectCreationExpression
))
else
if
(
initializerExpression
.
IsParentKind
(
SyntaxKind
.
ObjectCreationExpression
,
out
ObjectCreationExpressionSyntax
objectCreation
))
{
// new List<T> { Goo() }
var
objectCreation
=
(
ObjectCreationExpressionSyntax
)
initializerExpression
.
Parent
;
var
types
=
GetTypes
(
objectCreation
).
Select
(
t
=>
t
.
InferredType
);
if
(
types
.
Any
(
t
=>
t
is
INamedTypeSymbol
))
{
...
...
@@ -1679,10 +1676,10 @@ private IEnumerable<TypeInferenceInfo> InferTypeInNameColon(NameColonSyntax name
// context.
var
name
=
memberAccessExpression
.
Name
.
Identifier
.
Value
;
if
(
name
.
Equals
(
nameof
(
Task
<
int
>.
ConfigureAwait
))
&&
memberAccessExpression
.
IsParentKind
(
SyntaxKind
.
InvocationExpression
)
&&
memberAccessExpression
.
IsParentKind
(
SyntaxKind
.
InvocationExpression
,
out
InvocationExpressionSyntax
invocation
)
&&
memberAccessExpression
.
Parent
.
IsParentKind
(
SyntaxKind
.
AwaitExpression
))
{
return
InferTypes
(
(
ExpressionSyntax
)
memberAccessExpression
.
Parent
);
return
InferTypes
(
invocation
);
}
else
if
(
name
.
Equals
(
nameof
(
Task
<
int
>.
ContinueWith
)))
{
...
...
@@ -1704,9 +1701,8 @@ private IEnumerable<TypeInferenceInfo> InferTypeInNameColon(NameColonSyntax name
// goo.Select
// We want to infer IEnumerable<T>. We can try to figure out what
// T if we get a delegate as the first argument to Select/Where.
if
(
ienumerableType
!=
null
&&
memberAccessExpression
.
IsParentKind
(
SyntaxKind
.
InvocationExpression
))
if
(
ienumerableType
!=
null
&&
memberAccessExpression
.
IsParentKind
(
SyntaxKind
.
InvocationExpression
,
out
invocation
))
{
var
invocation
=
(
InvocationExpressionSyntax
)
memberAccessExpression
.
Parent
;
if
(
invocation
.
ArgumentList
.
Arguments
.
Count
>
0
)
{
var
argumentExpression
=
invocation
.
ArgumentList
.
Arguments
[
0
].
Expression
;
...
...
@@ -1719,10 +1715,9 @@ private IEnumerable<TypeInferenceInfo> InferTypeInNameColon(NameColonSyntax name
?
delegateType
.
TypeArguments
[
0
]
:
this
.
Compilation
.
ObjectType
;
if
(
IsUnusableType
(
typeArg
)
&&
argumentExpression
is
LambdaExpressionSyntax
)
if
(
IsUnusableType
(
typeArg
)
&&
argumentExpression
is
LambdaExpressionSyntax
lambdaExpression
)
{
typeArg
=
InferTypeForFirstParameterOfLambda
((
LambdaExpressionSyntax
)
argumentExpression
)
??
this
.
Compilation
.
ObjectType
;
typeArg
=
InferTypeForFirstParameterOfLambda
(
lambdaExpression
)
??
this
.
Compilation
.
ObjectType
;
}
return
CreateResult
(
ienumerableType
.
Construct
(
typeArg
));
...
...
@@ -2113,18 +2108,18 @@ private IEnumerable<TypeInferenceInfo> InferTypeInVariableDeclarator(VariableDec
private
IEnumerable
<
TypeInferenceInfo
>
InferTypeInVariableComponentAssignment
(
ExpressionSyntax
left
)
{
if
(
left
.
IsKind
(
SyntaxKind
.
DeclarationExpression
))
if
(
left
.
IsKind
(
SyntaxKind
.
DeclarationExpression
,
out
DeclarationExpressionSyntax
declExpr
))
{
return
GetTypes
(
((
DeclarationExpressionSyntax
)
left
)
.
Type
);
return
GetTypes
(
declExpr
.
Type
);
}
else
if
(
left
.
IsKind
(
SyntaxKind
.
TupleExpression
))
else
if
(
left
.
IsKind
(
SyntaxKind
.
TupleExpression
,
out
TupleExpressionSyntax
tupleExpression
))
{
// We have something of the form:
// (int a, int b) = ...
//
// This is a deconstruction, and a decent deconstructable type we can infer here
// is ValueTuple<int,int>.
var
tupleType
=
GetTupleType
(
(
TupleExpressionSyntax
)
left
);
var
tupleType
=
GetTupleType
(
tupleExpression
);
if
(
tupleType
!=
null
)
{
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录