Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
lwm1986
roslyn
提交
49e35a55
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,发现更多精彩内容 >>
未验证
提交
49e35a55
编写于
4月 21, 2020
作者:
A
Allison Chou
提交者:
GitHub
4月 21, 2020
浏览文件
操作
浏览文件
下载
差异文件
Merge pull request #43365 from allisonchou/PatternsFeature
Add keyword completion for new C# 9 patterns
上级
a0fa48a9
750d4e94
变更
13
隐藏空白更改
内联
并排
Showing
13 changed file
with
1498 addition
and
11 deletion
+1498
-11
src/EditorFeatures/CSharpTest2/Recommendations/AndKeywordRecommenderTests.cs
...CSharpTest2/Recommendations/AndKeywordRecommenderTests.cs
+505
-0
src/EditorFeatures/CSharpTest2/Recommendations/NotKeywordRecommenderTests.cs
...CSharpTest2/Recommendations/NotKeywordRecommenderTests.cs
+276
-0
src/EditorFeatures/CSharpTest2/Recommendations/OrKeywordRecommenderTests.cs
.../CSharpTest2/Recommendations/OrKeywordRecommenderTests.cs
+505
-0
src/Features/CSharp/Portable/Completion/CompletionProviders/KeywordCompletionProvider.cs
...mpletion/CompletionProviders/KeywordCompletionProvider.cs
+3
-0
src/Features/CSharp/Portable/Completion/KeywordRecommenders/AbstractNativeIntegerKeywordRecommender.cs
...rdRecommenders/AbstractNativeIntegerKeywordRecommender.cs
+1
-1
src/Features/CSharp/Portable/Completion/KeywordRecommenders/AndKeywordRecommender.cs
...e/Completion/KeywordRecommenders/AndKeywordRecommender.cs
+22
-0
src/Features/CSharp/Portable/Completion/KeywordRecommenders/NotKeywordRecommender.cs
...e/Completion/KeywordRecommenders/NotKeywordRecommender.cs
+22
-0
src/Features/CSharp/Portable/Completion/KeywordRecommenders/OrKeywordRecommender.cs
...le/Completion/KeywordRecommenders/OrKeywordRecommender.cs
+22
-0
src/Features/CSharp/Portable/Completion/KeywordRecommenders/VarKeywordRecommender.cs
...e/Completion/KeywordRecommenders/VarKeywordRecommender.cs
+1
-1
src/Workspaces/SharedUtilitiesAndExtensions/Workspace/CSharp/Extensions/ContextQuery/CSharpSyntaxContext.cs
...ace/CSharp/Extensions/ContextQuery/CSharpSyntaxContext.cs
+5
-3
src/Workspaces/SharedUtilitiesAndExtensions/Workspace/CSharp/Extensions/ContextQuery/SyntaxTreeExtensions.cs
...ce/CSharp/Extensions/ContextQuery/SyntaxTreeExtensions.cs
+128
-2
src/Workspaces/SharedUtilitiesAndExtensions/Workspace/Core/Extensions/ContextQuery/SyntaxContext.cs
...s/Workspace/Core/Extensions/ContextQuery/SyntaxContext.cs
+6
-3
src/Workspaces/SharedUtilitiesAndExtensions/Workspace/VisualBasic/Extensions/ContextQuery/VisualBasicSyntaxContext.vb
...Basic/Extensions/ContextQuery/VisualBasicSyntaxContext.vb
+2
-1
未找到文件。
src/EditorFeatures/CSharpTest2/Recommendations/AndKeywordRecommenderTests.cs
0 → 100644
浏览文件 @
49e35a55
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using
System.Threading.Tasks
;
using
Microsoft.CodeAnalysis.Test.Utilities
;
using
Xunit
;
namespace
Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.Recommendations
{
public
class
AndKeywordRecommenderTests
:
KeywordRecommenderTests
{
private
const
string
InitializeObjectE
=
@"var e = new object();
"
;
#if !CODE_STYLE
[
Fact
,
Trait
(
Traits
.
Feature
,
Traits
.
Features
.
KeywordRecommending
)]
public
async
Task
TestAfterConstant
()
{
await
VerifyKeywordAsync
(
AddInsideMethod
(
InitializeObjectE
+
@"if (e is 1 $$"
));
}
[
Fact
,
Trait
(
Traits
.
Feature
,
Traits
.
Features
.
KeywordRecommending
)]
public
async
Task
TestAfterMultipleConstants
()
{
await
VerifyKeywordAsync
(
AddInsideMethod
(
InitializeObjectE
+
@"if (e is 1 or 2 $$"
));
}
[
Fact
,
Trait
(
Traits
.
Feature
,
Traits
.
Features
.
KeywordRecommending
)]
public
async
Task
TestAfterType
()
{
await
VerifyKeywordAsync
(
AddInsideMethod
(
InitializeObjectE
+
@"if (e is int $$"
));
}
[
Fact
,
Trait
(
Traits
.
Feature
,
Traits
.
Features
.
KeywordRecommending
)]
public
async
Task
TestAfterRelationalOperator
()
{
await
VerifyKeywordAsync
(
AddInsideMethod
(
InitializeObjectE
+
@"if (e is >= 0 $$"
));
}
[
Fact
,
Trait
(
Traits
.
Feature
,
Traits
.
Features
.
KeywordRecommending
)]
public
async
Task
TestAfterGenericType
()
{
await
VerifyKeywordAsync
(
@"class C<T>
{
void M()
{
var e = new object();
if (e is T $$"
);
}
[
Fact
,
Trait
(
Traits
.
Feature
,
Traits
.
Features
.
KeywordRecommending
)]
public
async
Task
TestAfterArrayType
()
{
await
VerifyKeywordAsync
(
@"class C
{
void M()
{
var e = new object();
if (e is int[] $$"
);
}
[
Fact
,
Trait
(
Traits
.
Feature
,
Traits
.
Features
.
KeywordRecommending
)]
public
async
Task
TestAfterListType
()
{
await
VerifyKeywordAsync
(
@"using System.Collections.Generic;
class C
{
void M()
{
var e = new object();
if (e is List<int> $$"
);
}
[
Fact
,
Trait
(
Traits
.
Feature
,
Traits
.
Features
.
KeywordRecommending
)]
public
async
Task
TestAfterListType_FullyQualified
()
{
await
VerifyKeywordAsync
(
@"class C
{
void M()
{
var e = new object();
if (e is System.Collections.Generic.List<int> $$"
);
}
[
Fact
,
Trait
(
Traits
.
Feature
,
Traits
.
Features
.
KeywordRecommending
)]
public
async
Task
TestInsideSubpattern
()
{
await
VerifyKeywordAsync
(
@"class C
{
public int P { get; }
void M(C test)
{
if (test is { P: 1 $$"
);
}
[
Fact
,
Trait
(
Traits
.
Feature
,
Traits
.
Features
.
KeywordRecommending
)]
public
async
Task
TestInsideSubpattern_ComplexConstant
()
{
await
VerifyKeywordAsync
(
@"namespace N
{
class C
{
const int P = 1;
int Prop { get; }
void M(C test)
{
if (test is { Prop: N.C.P $$"
);
}
[
Fact
,
Trait
(
Traits
.
Feature
,
Traits
.
Features
.
KeywordRecommending
)]
public
async
Task
TestInsideSubpattern_AfterOpenParen
()
{
await
VerifyKeywordAsync
(
@"class C
{
int P { get; }
void M()
{
var C2 = new C();
if (C2 is { P: (1 $$"
);
}
[
Fact
,
Trait
(
Traits
.
Feature
,
Traits
.
Features
.
KeywordRecommending
)]
public
async
Task
TestInsideSubpattern_AfterOpenParen_ComplexConstant
()
{
await
VerifyKeywordAsync
(
@"namespace N
{
class C
{
const int P = 1;
int Prop { get; }
void M(C test)
{
if (test is { Prop: (N.C.P $$"
);
}
[
Fact
,
Trait
(
Traits
.
Feature
,
Traits
.
Features
.
KeywordRecommending
)]
public
async
Task
TestInsideSubpattern_AfterMultipleOpenParens
()
{
await
VerifyKeywordAsync
(
@"class C
{
int P { get; }
void M()
{
var C2 = new C();
if (C2 is { P: (((1 $$"
);
}
[
Fact
,
Trait
(
Traits
.
Feature
,
Traits
.
Features
.
KeywordRecommending
)]
public
async
Task
TestInsideSubpattern_AfterMultipleOpenParens_ComplexConstant
()
{
await
VerifyKeywordAsync
(
@"namespace N
{
class C
{
const int P = 1;
int Prop { get; }
void M(C test)
{
if (test is { Prop: (((N.C.P $$"
);
}
[
Fact
,
Trait
(
Traits
.
Feature
,
Traits
.
Features
.
KeywordRecommending
)]
public
async
Task
TestInsideSubpattern_AfterParenPair
()
{
await
VerifyKeywordAsync
(
@"class C
{
int P { get; }
void M()
{
var C2 = new C();
if (C2 is { P: (1) $$"
);
}
[
Fact
,
Trait
(
Traits
.
Feature
,
Traits
.
Features
.
KeywordRecommending
)]
public
async
Task
TestInsideSubpattern_AfterParenPair_ComplexConstant
()
{
await
VerifyKeywordAsync
(
@"namespace N
{
class C
{
const int P = 1;
int Prop { get; }
void M(C test)
{
if (test is { Prop: (N.C.P + 1) $$"
);
}
[
Fact
,
Trait
(
Traits
.
Feature
,
Traits
.
Features
.
KeywordRecommending
)]
public
async
Task
TestInsideSubpattern_AfterMultipleParenPairs
()
{
await
VerifyKeywordAsync
(
@"class C
{
int P { get; }
void M()
{
var C2 = new C();
if (C2 is { P: (((1))) $$"
);
}
[
Fact
,
Trait
(
Traits
.
Feature
,
Traits
.
Features
.
KeywordRecommending
)]
public
async
Task
TestInsideSubpattern_AfterMultipleParenPairs_ComplexConstant
()
{
await
VerifyKeywordAsync
(
@"namespace N
{
class C
{
const int P = 1;
int Prop { get; }
void M(C test)
{
if (test is { Prop: (((N.C.P))) $$"
);
}
[
Fact
,
Trait
(
Traits
.
Feature
,
Traits
.
Features
.
KeywordRecommending
)]
public
async
Task
TestAfterQualifiedName
()
{
await
VerifyKeywordAsync
(
@"class C
{
int P { get; }
void M()
{
var C2 = new C();
var e = new object();
if (e is C2.P $$"
);
}
[
Fact
,
Trait
(
Traits
.
Feature
,
Traits
.
Features
.
KeywordRecommending
)]
public
async
Task
TestAfterQualifiedName2
()
{
await
VerifyKeywordAsync
(
@"
namespace N
{
class C
{
const int P = 1;
void M()
{
var e = new object();
if (e is N.C.P $$"
);
}
[
Fact
,
Trait
(
Traits
.
Feature
,
Traits
.
Features
.
KeywordRecommending
)]
public
async
Task
TestAtBeginningOfSwitchExpression
()
{
await
VerifyKeywordAsync
(
AddInsideMethod
(
InitializeObjectE
+
@"var result = e switch
{
1 $$"
));
}
[
Fact
,
Trait
(
Traits
.
Feature
,
Traits
.
Features
.
KeywordRecommending
)]
public
async
Task
TestAtBeginningOfSwitchExpression_Complex
()
{
await
VerifyKeywordAsync
(
@"namespace N
{
class C
{
const int P = 1;
void M()
{
var e = new object();
var result = e switch
{
N.C.P $$"
);
}
[
Fact
,
Trait
(
Traits
.
Feature
,
Traits
.
Features
.
KeywordRecommending
)]
public
async
Task
TestAtBeginningOfSwitchStatement
()
{
await
VerifyKeywordAsync
(
AddInsideMethod
(
InitializeObjectE
+
@"switch (e)
{
case 1 $$"
));
}
[
Fact
,
Trait
(
Traits
.
Feature
,
Traits
.
Features
.
KeywordRecommending
)]
public
async
Task
TestAtBeginningOfSwitchExpression_AfterOpenParen
()
{
await
VerifyKeywordAsync
(
AddInsideMethod
(
InitializeObjectE
+
@"var result = e switch
{
(1 $$"
));
}
[
Fact
,
Trait
(
Traits
.
Feature
,
Traits
.
Features
.
KeywordRecommending
)]
public
async
Task
TestAtBeginningOfSwitchExpression_AfterOpenParen_Complex
()
{
await
VerifyKeywordAsync
(
@"namespace N
{
class C
{
const int P = 1;
void M()
{
var e = new object();
var result = e switch
{
(N.C.P $$"
);
}
[
Fact
,
Trait
(
Traits
.
Feature
,
Traits
.
Features
.
KeywordRecommending
)]
public
async
Task
TestAtBeginningOfSwitchExpression_AfterMultipleOpenParens
()
{
await
VerifyKeywordAsync
(
AddInsideMethod
(
InitializeObjectE
+
@"var result = e switch
{
(((1 $$"
));
}
[
Fact
,
Trait
(
Traits
.
Feature
,
Traits
.
Features
.
KeywordRecommending
)]
public
async
Task
TestAtBeginningOfSwitchExpression_AfterMultipleOpenParens_Complex
()
{
await
VerifyKeywordAsync
(
@"namespace N
{
class C
{
const int P = 1;
void M()
{
var e = new object();
var result = e switch
{
(((N.C.P $$"
);
}
[
Fact
,
Trait
(
Traits
.
Feature
,
Traits
.
Features
.
KeywordRecommending
)]
public
async
Task
TestAtBeginningOfSwitchStatement_AfterOpenParen
()
{
await
VerifyKeywordAsync
(
AddInsideMethod
(
InitializeObjectE
+
@"switch (e)
{
case (1 $$"
));
}
[
Fact
,
Trait
(
Traits
.
Feature
,
Traits
.
Features
.
KeywordRecommending
)]
public
async
Task
TestAtBeginningOfSwitchStatement_AfterMultipleOpenParens
()
{
await
VerifyKeywordAsync
(
AddInsideMethod
(
InitializeObjectE
+
@"switch (e)
{
case (((1 $$"
));
}
[
Fact
,
Trait
(
Traits
.
Feature
,
Traits
.
Features
.
KeywordRecommending
)]
public
async
Task
TestAtBeginningOfSwitchStatement_AfterMultipleOpenParens_MemberAccessExpression
()
{
await
VerifyKeywordAsync
(
@"namespace N
{
class C
{
const int P = 1;
void M()
{
var e = new object();
switch (e)
{
case (((N.C.P $$"
);
}
[
Fact
,
Trait
(
Traits
.
Feature
,
Traits
.
Features
.
KeywordRecommending
)]
public
async
Task
TestAtBeginningOfSwitchStatement_AfterMultipleOpenParens_MemberAccessExpression2
()
{
await
VerifyKeywordAsync
(
@"namespace N
{
class C
{
void M()
{
var e = new object();
switch (e)
{
case (((N.C $$"
);
}
[
Fact
,
Trait
(
Traits
.
Feature
,
Traits
.
Features
.
KeywordRecommending
)]
public
async
Task
TestMissingAfterIsKeyword
()
{
await
VerifyAbsenceAsync
(
AddInsideMethod
(
InitializeObjectE
+
@"if (e is $$"
));
}
[
Fact
,
Trait
(
Traits
.
Feature
,
Traits
.
Features
.
KeywordRecommending
)]
public
async
Task
TestMissingAfterNotKeyword
()
{
await
VerifyAbsenceAsync
(
AddInsideMethod
(
InitializeObjectE
+
@"if (e is not $$"
));
}
[
Fact
,
Trait
(
Traits
.
Feature
,
Traits
.
Features
.
KeywordRecommending
)]
public
async
Task
TestMissingAfterVarKeyword
()
{
await
VerifyAbsenceAsync
(
AddInsideMethod
(
InitializeObjectE
+
@"if (e is var $$"
));
}
[
Fact
,
Trait
(
Traits
.
Feature
,
Traits
.
Features
.
KeywordRecommending
)]
public
async
Task
TestMissingAfterAndKeyword
()
{
await
VerifyAbsenceAsync
(
AddInsideMethod
(
InitializeObjectE
+
@"if (e is 1 and $$"
));
}
[
Fact
,
Trait
(
Traits
.
Feature
,
Traits
.
Features
.
KeywordRecommending
)]
public
async
Task
TestMissingAfterOrKeyword
()
{
await
VerifyAbsenceAsync
(
AddInsideMethod
(
InitializeObjectE
+
@"if (e is 1 or $$"
));
}
[
Fact
,
Trait
(
Traits
.
Feature
,
Traits
.
Features
.
KeywordRecommending
)]
public
async
Task
TestMissingAfterOpenParen
()
{
await
VerifyAbsenceAsync
(
AddInsideMethod
(
InitializeObjectE
+
@"if (e is ($$"
));
}
[
Fact
,
Trait
(
Traits
.
Feature
,
Traits
.
Features
.
KeywordRecommending
)]
public
async
Task
TestMissingAfterOpenBracket
()
{
await
VerifyAbsenceAsync
(
AddInsideMethod
(
InitializeObjectE
+
@"if (e is { $$"
));
}
[
Fact
,
Trait
(
Traits
.
Feature
,
Traits
.
Features
.
KeywordRecommending
)]
public
async
Task
TestMissingAtBeginningOfSwitchExpression
()
{
await
VerifyAbsenceAsync
(
AddInsideMethod
(
InitializeObjectE
+
@"var result = e switch
{
$$"
));
}
[
Fact
,
Trait
(
Traits
.
Feature
,
Traits
.
Features
.
KeywordRecommending
)]
public
async
Task
TestMissingAtBeginningOfSwitchStatement
()
{
await
VerifyAbsenceAsync
(
AddInsideMethod
(
InitializeObjectE
+
@"switch (e)
{
case $$"
));
}
[
Fact
,
Trait
(
Traits
.
Feature
,
Traits
.
Features
.
KeywordRecommending
)]
public
async
Task
TestMissingAfterTypeAndOpenParen
()
{
await
VerifyAbsenceAsync
(
AddInsideMethod
(
InitializeObjectE
+
@"if (e is int ($$"
));
}
[
Fact
,
Trait
(
Traits
.
Feature
,
Traits
.
Features
.
KeywordRecommending
)]
public
async
Task
TestMissingAfterTypeAndCloseParen
()
{
await
VerifyAbsenceAsync
(
AddInsideMethod
(
InitializeObjectE
+
@"if (e is int)$$"
));
}
#endif
}
}
src/EditorFeatures/CSharpTest2/Recommendations/NotKeywordRecommenderTests.cs
0 → 100644
浏览文件 @
49e35a55
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using
System.Threading.Tasks
;
using
Microsoft.CodeAnalysis.Test.Utilities
;
using
Xunit
;
namespace
Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.Recommendations
{
public
class
NotKeywordRecommenderTests
:
KeywordRecommenderTests
{
private
const
string
InitializeObjectE
=
@"object e = new object();
"
;
#if !CODE_STYLE
[
Fact
,
Trait
(
Traits
.
Feature
,
Traits
.
Features
.
KeywordRecommending
)]
public
async
Task
TestAfterIsKeyword
()
{
await
VerifyKeywordAsync
(
AddInsideMethod
(
InitializeObjectE
+
@"if (e is $$"
));
}
[
Fact
,
Trait
(
Traits
.
Feature
,
Traits
.
Features
.
KeywordRecommending
)]
public
async
Task
TestAfterNotKeyword
()
{
await
VerifyKeywordAsync
(
AddInsideMethod
(
InitializeObjectE
+
@"if (e is not $$"
));
}
[
Fact
,
Trait
(
Traits
.
Feature
,
Traits
.
Features
.
KeywordRecommending
)]
public
async
Task
TestAfterNotKeywordAndOpenParen
()
{
await
VerifyKeywordAsync
(
AddInsideMethod
(
InitializeObjectE
+
@"if (e is not ($$"
));
}
[
Fact
,
Trait
(
Traits
.
Feature
,
Traits
.
Features
.
KeywordRecommending
)]
public
async
Task
TestAfterAndKeyword_IntExpression
()
{
await
VerifyKeywordAsync
(
AddInsideMethod
(
InitializeObjectE
+
@"if (e is 1 and $$"
));
}
[
Fact
,
Trait
(
Traits
.
Feature
,
Traits
.
Features
.
KeywordRecommending
)]
public
async
Task
TestAfterAndKeyword_StrExpression
()
{
await
VerifyKeywordAsync
(
AddInsideMethod
(
InitializeObjectE
+
@"if (e is ""str"" and $$"
));
}
[
Fact
,
Trait
(
Traits
.
Feature
,
Traits
.
Features
.
KeywordRecommending
)]
public
async
Task
TestAfterAndKeyword_RelationalExpression
()
{
await
VerifyKeywordAsync
(
AddInsideMethod
(
InitializeObjectE
+
@"if (e is <= 1 and $$"
));
}
[
Fact
,
Trait
(
Traits
.
Feature
,
Traits
.
Features
.
KeywordRecommending
)]
public
async
Task
TestAfterOpenParen
()
{
await
VerifyKeywordAsync
(
AddInsideMethod
(
InitializeObjectE
+
@"if (e is ($$"
));
}
[
Fact
,
Trait
(
Traits
.
Feature
,
Traits
.
Features
.
KeywordRecommending
)]
public
async
Task
TestAfterMultipleOpenParen
()
{
await
VerifyKeywordAsync
(
AddInsideMethod
(
InitializeObjectE
+
@"if (e is ((($$"
));
}
[
Fact
,
Trait
(
Traits
.
Feature
,
Traits
.
Features
.
KeywordRecommending
)]
public
async
Task
TestInMiddleofCompletePattern
()
{
await
VerifyKeywordAsync
(
AddInsideMethod
(
InitializeObjectE
+
@"if (e is $$ 1 or 2)"
));
}
[
Fact
,
Trait
(
Traits
.
Feature
,
Traits
.
Features
.
KeywordRecommending
)]
public
async
Task
TestInMiddleOfCompleteQualifiedPattern
()
{
await
VerifyKeywordAsync
(
@"namespace N
{
class C
{
const int P = 1;
void M()
{
if (e is $$ N.C.P or 2) { }
}
}
}"
);
}
[
Fact
,
Trait
(
Traits
.
Feature
,
Traits
.
Features
.
KeywordRecommending
)]
public
async
Task
TestInMiddleOfCompleteQualifiedPattern_List
()
{
await
VerifyKeywordAsync
(
@"namespace N
{
class C
{
const int P = 1;
void M()
{
if (e is $$ System.Collections.Generic.List<int> or 2) { }
}
}
}"
);
}
[
Fact
,
Trait
(
Traits
.
Feature
,
Traits
.
Features
.
KeywordRecommending
)]
public
async
Task
TestInMiddleofCompletePattern_MultipleParens
()
{
await
VerifyKeywordAsync
(
AddInsideMethod
(
InitializeObjectE
+
@"if (e is ((($$ 1 or 2))))"
));
}
[
Fact
,
Trait
(
Traits
.
Feature
,
Traits
.
Features
.
KeywordRecommending
)]
public
async
Task
TestAtBeginningOfSwitchExpression
()
{
await
VerifyKeywordAsync
(
AddInsideMethod
(
InitializeObjectE
+
@"var result = e switch
{
$$"
));
}
[
Fact
,
Trait
(
Traits
.
Feature
,
Traits
.
Features
.
KeywordRecommending
)]
public
async
Task
TestAtBeginningOfSwitchStatement
()
{
await
VerifyKeywordAsync
(
AddInsideMethod
(
InitializeObjectE
+
@"switch (e)
{
case $$"
));
}
[
Fact
,
Trait
(
Traits
.
Feature
,
Traits
.
Features
.
KeywordRecommending
)]
public
async
Task
TestInMiddleOfSwitchExpression
()
{
await
VerifyKeywordAsync
(
AddInsideMethod
(
InitializeObjectE
+
@"var result = e switch
{
1 => 2,
$$"
));
}
[
Fact
,
Trait
(
Traits
.
Feature
,
Traits
.
Features
.
KeywordRecommending
)]
public
async
Task
TestInMiddleOfSwitchStatement
()
{
await
VerifyKeywordAsync
(
AddInsideMethod
(
InitializeObjectE
+
@"switch (e)
{
case 1:
case $$"
));
}
[
Fact
,
Trait
(
Traits
.
Feature
,
Traits
.
Features
.
KeywordRecommending
)]
public
async
Task
TestAtBeginningOfSwitchExpression_AfterOpenParen
()
{
await
VerifyKeywordAsync
(
AddInsideMethod
(
InitializeObjectE
+
@"var result = e switch
{
($$"
));
}
[
Fact
,
Trait
(
Traits
.
Feature
,
Traits
.
Features
.
KeywordRecommending
)]
public
async
Task
TestInMiddleOfSwitchExpression_AfterOpenParen
()
{
await
VerifyKeywordAsync
(
AddInsideMethod
(
InitializeObjectE
+
@"var result = e switch
{
1 => 2,
($$"
));
}
[
Fact
,
Trait
(
Traits
.
Feature
,
Traits
.
Features
.
KeywordRecommending
)]
public
async
Task
TestInMiddleOfSwitchExpression_ComplexCase
()
{
await
VerifyKeywordAsync
(
AddInsideMethod
(
InitializeObjectE
+
@"var result = e switch
{
1 and ($$"
));
}
[
Fact
,
Trait
(
Traits
.
Feature
,
Traits
.
Features
.
KeywordRecommending
)]
public
async
Task
TestAtBeginningOfSwitchStatement_AfterOpenParen
()
{
await
VerifyKeywordAsync
(
AddInsideMethod
(
InitializeObjectE
+
@"switch (e)
{
case ($$"
));
}
[
Fact
,
Trait
(
Traits
.
Feature
,
Traits
.
Features
.
KeywordRecommending
)]
public
async
Task
TestAtBeginningOfSwitchStatement_AfterOpenParen_CompleteStatement
()
{
await
VerifyKeywordAsync
(
AddInsideMethod
(
InitializeObjectE
+
@"switch (e)
{
case ($$ 1)"
));
}
[
Fact
,
Trait
(
Traits
.
Feature
,
Traits
.
Features
.
KeywordRecommending
)]
public
async
Task
TestInsideSubpattern
()
{
await
VerifyKeywordAsync
(
@"class C
{
public int P { get; }
void M(C test)
{
if (test is { P: $$"
);
}
[
Fact
,
Trait
(
Traits
.
Feature
,
Traits
.
Features
.
KeywordRecommending
)]
public
async
Task
TestInsideSubpattern_AfterOpenParen
()
{
await
VerifyKeywordAsync
(
@"class C
{
public int P { get; }
void M(C test)
{
if (test is { P: ($$"
);
}
[
Fact
,
Trait
(
Traits
.
Feature
,
Traits
.
Features
.
KeywordRecommending
)]
public
async
Task
TestInsideSubpattern_AfterOpenParen_Complex
()
{
await
VerifyKeywordAsync
(
@"class C
{
public int P { get; }
void M(C test)
{
if (test is { P: (1 or $$"
);
}
[
Fact
,
Trait
(
Traits
.
Feature
,
Traits
.
Features
.
KeywordRecommending
)]
public
async
Task
TestMissingAfterConstant
()
{
await
VerifyAbsenceAsync
(
AddInsideMethod
(
InitializeObjectE
+
@"if (e is 1 $$"
));
}
[
Fact
,
Trait
(
Traits
.
Feature
,
Traits
.
Features
.
KeywordRecommending
)]
public
async
Task
TestMissingAfterMultipleConstants
()
{
await
VerifyAbsenceAsync
(
AddInsideMethod
(
InitializeObjectE
+
@"if (e is 1 or 2 $$"
));
}
[
Fact
,
Trait
(
Traits
.
Feature
,
Traits
.
Features
.
KeywordRecommending
)]
public
async
Task
TestAfterType
()
{
await
VerifyAbsenceAsync
(
AddInsideMethod
(
InitializeObjectE
+
@"if (e is int $$"
));
}
[
Fact
,
Trait
(
Traits
.
Feature
,
Traits
.
Features
.
KeywordRecommending
)]
public
async
Task
TestAfterRelationalOperator
()
{
await
VerifyAbsenceAsync
(
AddInsideMethod
(
InitializeObjectE
+
@"if (e is >= 0 $$"
));
}
#endif
}
}
src/EditorFeatures/CSharpTest2/Recommendations/OrKeywordRecommenderTests.cs
0 → 100644
浏览文件 @
49e35a55
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using
System.Threading.Tasks
;
using
Microsoft.CodeAnalysis.Test.Utilities
;
using
Xunit
;
namespace
Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.Recommendations
{
public
class
OrKeywordRecommenderTests
:
KeywordRecommenderTests
{
private
const
string
InitializeObjectE
=
@"var e = new object();
"
;
#if !CODE_STYLE
[
Fact
,
Trait
(
Traits
.
Feature
,
Traits
.
Features
.
KeywordRecommending
)]
public
async
Task
TestAfterConstant
()
{
await
VerifyKeywordAsync
(
AddInsideMethod
(
InitializeObjectE
+
@"if (e is 1 $$"
));
}
[
Fact
,
Trait
(
Traits
.
Feature
,
Traits
.
Features
.
KeywordRecommending
)]
public
async
Task
TestAfterMultipleConstants
()
{
await
VerifyKeywordAsync
(
AddInsideMethod
(
InitializeObjectE
+
@"if (e is 1 or 2 $$"
));
}
[
Fact
,
Trait
(
Traits
.
Feature
,
Traits
.
Features
.
KeywordRecommending
)]
public
async
Task
TestAfterType
()
{
await
VerifyKeywordAsync
(
AddInsideMethod
(
InitializeObjectE
+
@"if (e is int $$"
));
}
[
Fact
,
Trait
(
Traits
.
Feature
,
Traits
.
Features
.
KeywordRecommending
)]
public
async
Task
TestAfterRelationalOperator
()
{
await
VerifyKeywordAsync
(
AddInsideMethod
(
InitializeObjectE
+
@"if (e is >= 0 $$"
));
}
[
Fact
,
Trait
(
Traits
.
Feature
,
Traits
.
Features
.
KeywordRecommending
)]
public
async
Task
TestAfterGenericType
()
{
await
VerifyKeywordAsync
(
@"class C<T>
{
void M()
{
var e = new object();
if (e is T $$"
);
}
[
Fact
,
Trait
(
Traits
.
Feature
,
Traits
.
Features
.
KeywordRecommending
)]
public
async
Task
TestAfterArrayType
()
{
await
VerifyKeywordAsync
(
@"class C
{
void M()
{
var e = new object();
if (e is int[] $$"
);
}
[
Fact
,
Trait
(
Traits
.
Feature
,
Traits
.
Features
.
KeywordRecommending
)]
public
async
Task
TestAfterListType
()
{
await
VerifyKeywordAsync
(
@"using System.Collections.Generic;
class C
{
void M()
{
var e = new object();
if (e is List<int> $$"
);
}
[
Fact
,
Trait
(
Traits
.
Feature
,
Traits
.
Features
.
KeywordRecommending
)]
public
async
Task
TestAfterListType_FullyQualified
()
{
await
VerifyKeywordAsync
(
@"class C
{
void M()
{
var e = new object();
if (e is System.Collections.Generic.List<int> $$"
);
}
[
Fact
,
Trait
(
Traits
.
Feature
,
Traits
.
Features
.
KeywordRecommending
)]
public
async
Task
TestInsideSubpattern
()
{
await
VerifyKeywordAsync
(
@"class C
{
public int P { get; }
void M(C test)
{
if (test is { P: 1 $$"
);
}
[
Fact
,
Trait
(
Traits
.
Feature
,
Traits
.
Features
.
KeywordRecommending
)]
public
async
Task
TestInsideSubpattern_ComplexConstant
()
{
await
VerifyKeywordAsync
(
@"namespace N
{
class C
{
const int P = 1;
int Prop { get; }
void M(C test)
{
if (test is { Prop: N.C.P $$"
);
}
[
Fact
,
Trait
(
Traits
.
Feature
,
Traits
.
Features
.
KeywordRecommending
)]
public
async
Task
TestInsideSubpattern_AfterOpenParen
()
{
await
VerifyKeywordAsync
(
@"class C
{
int P { get; }
void M()
{
var C2 = new C();
if (C2 is { P: (1 $$"
);
}
[
Fact
,
Trait
(
Traits
.
Feature
,
Traits
.
Features
.
KeywordRecommending
)]
public
async
Task
TestInsideSubpattern_AfterOpenParen_ComplexConstant
()
{
await
VerifyKeywordAsync
(
@"namespace N
{
class C
{
const int P = 1;
int Prop { get; }
void M(C test)
{
if (test is { Prop: (N.C.P $$"
);
}
[
Fact
,
Trait
(
Traits
.
Feature
,
Traits
.
Features
.
KeywordRecommending
)]
public
async
Task
TestInsideSubpattern_AfterMultipleOpenParens
()
{
await
VerifyKeywordAsync
(
@"class C
{
int P { get; }
void M()
{
var C2 = new C();
if (C2 is { P: (((1 $$"
);
}
[
Fact
,
Trait
(
Traits
.
Feature
,
Traits
.
Features
.
KeywordRecommending
)]
public
async
Task
TestInsideSubpattern_AfterMultipleOpenParens_ComplexConstant
()
{
await
VerifyKeywordAsync
(
@"namespace N
{
class C
{
const int P = 1;
int Prop { get; }
void M(C test)
{
if (test is { Prop: (((N.C.P $$"
);
}
[
Fact
,
Trait
(
Traits
.
Feature
,
Traits
.
Features
.
KeywordRecommending
)]
public
async
Task
TestAtBeginningOfSwitchStatement_AfterMultipleOpenParens_MemberAccessExpression
()
{
await
VerifyKeywordAsync
(
@"namespace N
{
class C
{
const int P = 1;
void M()
{
var e = new object();
switch (e)
{
case (((N.C.P $$"
);
}
[
Fact
,
Trait
(
Traits
.
Feature
,
Traits
.
Features
.
KeywordRecommending
)]
public
async
Task
TestAtBeginningOfSwitchStatement_AfterMultipleOpenParens_MemberAccessExpression2
()
{
await
VerifyKeywordAsync
(
@"namespace N
{
class C
{
void M()
{
var e = new object();
switch (e)
{
case (((N.C $$"
);
}
[
Fact
,
Trait
(
Traits
.
Feature
,
Traits
.
Features
.
KeywordRecommending
)]
public
async
Task
TestInsideSubpattern_AfterParenPair
()
{
await
VerifyKeywordAsync
(
@"class C
{
int P { get; }
void M()
{
var C2 = new C();
if (C2 is { P: (1) $$"
);
}
[
Fact
,
Trait
(
Traits
.
Feature
,
Traits
.
Features
.
KeywordRecommending
)]
public
async
Task
TestInsideSubpattern_AfterParenPair_ComplexConstant
()
{
await
VerifyKeywordAsync
(
@"namespace N
{
class C
{
const int P = 1;
int Prop { get; }
void M(C test)
{
if (test is { Prop: (N.C.P + 1) $$"
);
}
[
Fact
,
Trait
(
Traits
.
Feature
,
Traits
.
Features
.
KeywordRecommending
)]
public
async
Task
TestInsideSubpattern_AfterMultipleParenPairs
()
{
await
VerifyKeywordAsync
(
@"class C
{
int P { get; }
void M()
{
var C2 = new C();
if (C2 is { P: (((1))) $$"
);
}
[
Fact
,
Trait
(
Traits
.
Feature
,
Traits
.
Features
.
KeywordRecommending
)]
public
async
Task
TestInsideSubpattern_AfterMultipleParenPairs_ComplexConstant
()
{
await
VerifyKeywordAsync
(
@"namespace N
{
class C
{
const int P = 1;
int Prop { get; }
void M(C test)
{
if (test is { Prop: (((N.C.P))) $$"
);
}
[
Fact
,
Trait
(
Traits
.
Feature
,
Traits
.
Features
.
KeywordRecommending
)]
public
async
Task
TestAfterQualifiedName
()
{
await
VerifyKeywordAsync
(
@"class C
{
int P { get; }
void M()
{
var C2 = new C();
var e = new object();
if (e is C2.P $$"
);
}
[
Fact
,
Trait
(
Traits
.
Feature
,
Traits
.
Features
.
KeywordRecommending
)]
public
async
Task
TestAfterQualifiedName2
()
{
await
VerifyKeywordAsync
(
@"
namespace N
{
class C
{
const int P = 1;
void M()
{
var e = new object();
if (e is N.C.P $$"
);
}
[
Fact
,
Trait
(
Traits
.
Feature
,
Traits
.
Features
.
KeywordRecommending
)]
public
async
Task
TestAtBeginningOfSwitchExpression
()
{
await
VerifyKeywordAsync
(
AddInsideMethod
(
InitializeObjectE
+
@"var result = e switch
{
1 $$"
));
}
[
Fact
,
Trait
(
Traits
.
Feature
,
Traits
.
Features
.
KeywordRecommending
)]
public
async
Task
TestAtBeginningOfSwitchExpression_Complex
()
{
await
VerifyKeywordAsync
(
@"namespace N
{
class C
{
const int P = 1;
void M()
{
var e = new object();
var result = e switch
{
N.C.P $$"
);
}
[
Fact
,
Trait
(
Traits
.
Feature
,
Traits
.
Features
.
KeywordRecommending
)]
public
async
Task
TestAtBeginningOfSwitchStatement
()
{
await
VerifyKeywordAsync
(
AddInsideMethod
(
InitializeObjectE
+
@"switch (e)
{
case 1 $$"
));
}
[
Fact
,
Trait
(
Traits
.
Feature
,
Traits
.
Features
.
KeywordRecommending
)]
public
async
Task
TestAtBeginningOfSwitchExpression_AfterOpenParen
()
{
await
VerifyKeywordAsync
(
AddInsideMethod
(
InitializeObjectE
+
@"var result = e switch
{
(1 $$"
));
}
[
Fact
,
Trait
(
Traits
.
Feature
,
Traits
.
Features
.
KeywordRecommending
)]
public
async
Task
TestAtBeginningOfSwitchExpression_AfterOpenParen_Complex
()
{
await
VerifyKeywordAsync
(
@"namespace N
{
class C
{
const int P = 1;
void M()
{
var e = new object();
var result = e switch
{
(N.C.P $$"
);
}
[
Fact
,
Trait
(
Traits
.
Feature
,
Traits
.
Features
.
KeywordRecommending
)]
public
async
Task
TestAtBeginningOfSwitchExpression_AfterMultipleOpenParens
()
{
await
VerifyKeywordAsync
(
AddInsideMethod
(
InitializeObjectE
+
@"var result = e switch
{
(((1 $$"
));
}
[
Fact
,
Trait
(
Traits
.
Feature
,
Traits
.
Features
.
KeywordRecommending
)]
public
async
Task
TestAtBeginningOfSwitchExpression_AfterMultipleOpenParens_Complex
()
{
await
VerifyKeywordAsync
(
@"namespace N
{
class C
{
const int P = 1;
void M()
{
var e = new object();
var result = e switch
{
(((N.C.P $$"
);
}
[
Fact
,
Trait
(
Traits
.
Feature
,
Traits
.
Features
.
KeywordRecommending
)]
public
async
Task
TestAtBeginningOfSwitchStatement_AfterOpenParen
()
{
await
VerifyKeywordAsync
(
AddInsideMethod
(
InitializeObjectE
+
@"switch (e)
{
case (1 $$"
));
}
[
Fact
,
Trait
(
Traits
.
Feature
,
Traits
.
Features
.
KeywordRecommending
)]
public
async
Task
TestAtBeginningOfSwitchStatement_AfterMultipleOpenParens
()
{
await
VerifyKeywordAsync
(
AddInsideMethod
(
InitializeObjectE
+
@"switch (e)
{
case (((1 $$"
));
}
[
Fact
,
Trait
(
Traits
.
Feature
,
Traits
.
Features
.
KeywordRecommending
)]
public
async
Task
TestMissingAfterIsKeyword
()
{
await
VerifyAbsenceAsync
(
AddInsideMethod
(
InitializeObjectE
+
@"if (e is $$"
));
}
[
Fact
,
Trait
(
Traits
.
Feature
,
Traits
.
Features
.
KeywordRecommending
)]
public
async
Task
TestMissingAfterNotKeyword
()
{
await
VerifyAbsenceAsync
(
AddInsideMethod
(
InitializeObjectE
+
@"if (e is not $$"
));
}
[
Fact
,
Trait
(
Traits
.
Feature
,
Traits
.
Features
.
KeywordRecommending
)]
public
async
Task
TestMissingAfterVarKeyword
()
{
await
VerifyAbsenceAsync
(
AddInsideMethod
(
InitializeObjectE
+
@"if (e is var $$"
));
}
[
Fact
,
Trait
(
Traits
.
Feature
,
Traits
.
Features
.
KeywordRecommending
)]
public
async
Task
TestMissingAfterAndKeyword
()
{
await
VerifyAbsenceAsync
(
AddInsideMethod
(
InitializeObjectE
+
@"if (e is 1 and $$"
));
}
[
Fact
,
Trait
(
Traits
.
Feature
,
Traits
.
Features
.
KeywordRecommending
)]
public
async
Task
TestMissingAfterOrKeyword
()
{
await
VerifyAbsenceAsync
(
AddInsideMethod
(
InitializeObjectE
+
@"if (e is 1 or $$"
));
}
[
Fact
,
Trait
(
Traits
.
Feature
,
Traits
.
Features
.
KeywordRecommending
)]
public
async
Task
TestMissingAfterOpenParen
()
{
await
VerifyAbsenceAsync
(
AddInsideMethod
(
InitializeObjectE
+
@"if (e is ($$"
));
}
[
Fact
,
Trait
(
Traits
.
Feature
,
Traits
.
Features
.
KeywordRecommending
)]
public
async
Task
TestMissingAfterOpenBracket
()
{
await
VerifyAbsenceAsync
(
AddInsideMethod
(
InitializeObjectE
+
@"if (e is { $$"
));
}
[
Fact
,
Trait
(
Traits
.
Feature
,
Traits
.
Features
.
KeywordRecommending
)]
public
async
Task
TestMissingAtBeginningOfSwitchExpression
()
{
await
VerifyAbsenceAsync
(
AddInsideMethod
(
InitializeObjectE
+
@"var result = e switch
{
$$"
));
}
[
Fact
,
Trait
(
Traits
.
Feature
,
Traits
.
Features
.
KeywordRecommending
)]
public
async
Task
TestMissingAtBeginningOfSwitchStatement
()
{
await
VerifyAbsenceAsync
(
AddInsideMethod
(
InitializeObjectE
+
@"switch (e)
{
case $$"
));
}
[
Fact
,
Trait
(
Traits
.
Feature
,
Traits
.
Features
.
KeywordRecommending
)]
public
async
Task
TestMissingAfterTypeAndOpenParen
()
{
await
VerifyAbsenceAsync
(
AddInsideMethod
(
InitializeObjectE
+
@"if (e is int ($$"
));
}
[
Fact
,
Trait
(
Traits
.
Feature
,
Traits
.
Features
.
KeywordRecommending
)]
public
async
Task
TestMissingAfterTypeAndCloseParen
()
{
await
VerifyAbsenceAsync
(
AddInsideMethod
(
InitializeObjectE
+
@"if (e is int)$$"
));
}
#endif
}
}
src/Features/CSharp/Portable/Completion/CompletionProviders/KeywordCompletionProvider.cs
浏览文件 @
49e35a55
...
...
@@ -37,6 +37,7 @@ private static ImmutableArray<IKeywordRecommender<CSharpSyntaxContext>> GetKeywo
new
AbstractKeywordRecommender
(),
new
AddKeywordRecommender
(),
new
AliasKeywordRecommender
(),
new
AndKeywordRecommender
(),
new
AnnotationsKeywordRecommender
(),
new
AscendingKeywordRecommender
(),
new
AsKeywordRecommender
(),
...
...
@@ -109,6 +110,7 @@ private static ImmutableArray<IKeywordRecommender<CSharpSyntaxContext>> GetKeywo
new
NamespaceKeywordRecommender
(),
new
NewKeywordRecommender
(),
new
NintKeywordRecommender
(),
new
NotKeywordRecommender
(),
new
NotNullKeywordRecommender
(),
new
NuintKeywordRecommender
(),
new
NullableKeywordRecommender
(),
...
...
@@ -117,6 +119,7 @@ private static ImmutableArray<IKeywordRecommender<CSharpSyntaxContext>> GetKeywo
new
OnKeywordRecommender
(),
new
OperatorKeywordRecommender
(),
new
OrderByKeywordRecommender
(),
new
OrKeywordRecommender
(),
new
OutKeywordRecommender
(),
new
OverrideKeywordRecommender
(),
new
ParamKeywordRecommender
(),
...
...
src/Features/CSharp/Portable/Completion/KeywordRecommenders/AbstractNativeIntegerKeywordRecommender.cs
浏览文件 @
49e35a55
...
...
@@ -20,7 +20,7 @@ private static bool IsValidContext(CSharpSyntaxContext context)
if
(
context
.
IsStatementContext
||
context
.
IsGlobalStatementContext
||
context
.
IsPossibleTupleContext
||
context
.
Is
PatternContext
||
context
.
Is
AtStartOfPattern
||
(
context
.
IsTypeContext
&&
!
context
.
IsEnumBaseListContext
))
{
return
true
;
...
...
src/Features/CSharp/Portable/Completion/KeywordRecommenders/AndKeywordRecommender.cs
0 → 100644
浏览文件 @
49e35a55
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using
System.Threading
;
using
Microsoft.CodeAnalysis.CSharp.Extensions.ContextQuery
;
namespace
Microsoft.CodeAnalysis.CSharp.Completion.KeywordRecommenders
{
internal
class
AndKeywordRecommender
:
AbstractSyntacticSingleKeywordRecommender
{
public
AndKeywordRecommender
()
:
base
(
SyntaxKind
.
AndKeyword
)
{
}
protected
override
bool
IsValidContext
(
int
position
,
CSharpSyntaxContext
context
,
CancellationToken
cancellationToken
)
{
return
context
.
IsAtEndOfPattern
;
}
}
}
src/Features/CSharp/Portable/Completion/KeywordRecommenders/NotKeywordRecommender.cs
0 → 100644
浏览文件 @
49e35a55
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using
System.Threading
;
using
Microsoft.CodeAnalysis.CSharp.Extensions.ContextQuery
;
namespace
Microsoft.CodeAnalysis.CSharp.Completion.KeywordRecommenders
{
internal
class
NotKeywordRecommender
:
AbstractSyntacticSingleKeywordRecommender
{
public
NotKeywordRecommender
()
:
base
(
SyntaxKind
.
NotKeyword
)
{
}
protected
override
bool
IsValidContext
(
int
position
,
CSharpSyntaxContext
context
,
CancellationToken
cancellationToken
)
{
return
context
.
IsAtStartOfPattern
;
}
}
}
src/Features/CSharp/Portable/Completion/KeywordRecommenders/OrKeywordRecommender.cs
0 → 100644
浏览文件 @
49e35a55
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using
System.Threading
;
using
Microsoft.CodeAnalysis.CSharp.Extensions.ContextQuery
;
namespace
Microsoft.CodeAnalysis.CSharp.Completion.KeywordRecommenders
{
internal
class
OrKeywordRecommender
:
AbstractSyntacticSingleKeywordRecommender
{
public
OrKeywordRecommender
()
:
base
(
SyntaxKind
.
OrKeyword
)
{
}
protected
override
bool
IsValidContext
(
int
position
,
CSharpSyntaxContext
context
,
CancellationToken
cancellationToken
)
{
return
context
.
IsAtEndOfPattern
;
}
}
}
src/Features/CSharp/Portable/Completion/KeywordRecommenders/VarKeywordRecommender.cs
浏览文件 @
49e35a55
...
...
@@ -22,7 +22,7 @@ private static bool IsValidContext(CSharpSyntaxContext context)
if
(
context
.
IsStatementContext
||
context
.
IsGlobalStatementContext
||
context
.
IsPossibleTupleContext
||
context
.
Is
PatternContext
)
context
.
Is
AtStartOfPattern
)
{
return
true
;
}
...
...
src/Workspaces/SharedUtilitiesAndExtensions/Workspace/CSharp/Extensions/ContextQuery/CSharpSyntaxContext.cs
浏览文件 @
49e35a55
...
...
@@ -102,7 +102,8 @@ internal sealed class CSharpSyntaxContext : SyntaxContext
bool
isCatchFilterContext
,
bool
isDestructorTypeContext
,
bool
isPossibleTupleContext
,
bool
isPatternContext
,
bool
isStartPatternContext
,
bool
isAfterPatternContext
,
bool
isRightSideOfNumericType
,
bool
isInArgumentList
,
CancellationToken
cancellationToken
)
...
...
@@ -112,7 +113,7 @@ internal sealed class CSharpSyntaxContext : SyntaxContext
isRightOfDotOrArrowOrColonColon
,
isStatementContext
,
isAnyExpressionContext
,
isAttributeNameContext
,
isEnumTypeMemberAccessContext
,
isNameOfContext
,
isInQuery
,
isInImportsDirective
,
IsWithinAsyncMethod
(),
isPossibleTupleContext
,
isPatternContext
,
isRightSideOfNumericType
,
isInArgumentList
,
is
StartPatternContext
,
isAfter
PatternContext
,
isRightSideOfNumericType
,
isInArgumentList
,
cancellationToken
)
{
this
.
ContainingTypeDeclaration
=
containingTypeDeclaration
;
...
...
@@ -260,7 +261,8 @@ private static CSharpSyntaxContext CreateContextWorker(Workspace workspace, Sema
isCatchFilterContext
:
syntaxTree
.
IsCatchFilterContext
(
position
,
leftToken
),
isDestructorTypeContext
:
isDestructorTypeContext
,
isPossibleTupleContext
:
syntaxTree
.
IsPossibleTupleContext
(
leftToken
,
position
),
isPatternContext
:
syntaxTree
.
IsPatternContext
(
leftToken
,
position
),
isStartPatternContext
:
syntaxTree
.
IsAtStartOfPattern
(
leftToken
,
position
),
isAfterPatternContext
:
syntaxTree
.
IsAtEndOfPattern
(
leftToken
,
position
),
isRightSideOfNumericType
:
isRightSideOfNumericType
,
isInArgumentList
:
isArgumentListToken
,
cancellationToken
:
cancellationToken
);
...
...
src/Workspaces/SharedUtilitiesAndExtensions/Workspace/CSharp/Extensions/ContextQuery/SyntaxTreeExtensions.cs
浏览文件 @
49e35a55
...
...
@@ -1253,10 +1253,28 @@ public static bool IsPossibleTupleContext(this SyntaxTree syntaxTree, SyntaxToke
return
false
;
}
public
static
bool
Is
PatternContext
(
this
SyntaxTree
syntaxTree
,
SyntaxToken
leftToken
,
int
position
)
public
static
bool
Is
AtStartOfPattern
(
this
SyntaxTree
syntaxTree
,
SyntaxToken
leftToken
,
int
position
)
{
leftToken
=
leftToken
.
GetPreviousTokenIfTouchingWord
(
position
);
if
(
leftToken
.
IsKind
(
SyntaxKind
.
OpenParenToken
))
{
if
(
leftToken
.
Parent
.
IsKind
(
SyntaxKind
.
ParenthesizedExpression
,
out
ParenthesizedExpressionSyntax
parenthesizedExpression
))
{
// If we're dealing with an expression surrounded by one or more sets of open parentheses, we need to
// walk up the parens in order to see if we're actually at the start of a valid pattern or not.
return
IsAtStartOfPattern
(
syntaxTree
,
parenthesizedExpression
.
GetFirstToken
().
GetPreviousToken
(),
parenthesizedExpression
.
SpanStart
);
}
#if !CODE_STYLE
// e is ((($$ 1 or 2)))
if
(
leftToken
.
Parent
.
IsKind
(
SyntaxKind
.
ParenthesizedPattern
))
{
return
true
;
}
#endif
}
// case $$
// is $$
if
(
leftToken
.
IsKind
(
SyntaxKind
.
CaseKeyword
,
SyntaxKind
.
IsKeyword
))
...
...
@@ -1286,7 +1304,115 @@ public static bool IsPatternContext(this SyntaxTree syntaxTree, SyntaxToken left
return
true
;
}
#if !CODE_STYLE
// e is 1 and $$
// e is 1 or $$
if
(
leftToken
.
IsKind
(
SyntaxKind
.
AndKeyword
)
||
leftToken
.
IsKind
(
SyntaxKind
.
OrKeyword
))
{
return
leftToken
.
Parent
is
BinaryPatternSyntax
;
}
// e is not $$
if
(
leftToken
.
IsKind
(
SyntaxKind
.
NotKeyword
)
&&
leftToken
.
Parent
.
IsKind
(
SyntaxKind
.
NotPattern
))
{
return
true
;
}
#endif
return
false
;
}
public
static
bool
IsAtEndOfPattern
(
this
SyntaxTree
syntaxTree
,
SyntaxToken
leftToken
,
int
position
)
{
#if CODE_STYLE
return
false
;
#else
var
originalLeftToken
=
leftToken
;
leftToken
=
leftToken
.
GetPreviousTokenIfTouchingWord
(
position
);
var
patternSyntax
=
leftToken
.
GetAncestor
<
PatternSyntax
>();
if
(
patternSyntax
!=
null
)
{
var
lastTokenInPattern
=
patternSyntax
.
GetLastToken
();
// This check should cover the majority of cases, e.g.:
// e is 1 $$
// e is >= 0 $$
// e is { P: (1 $$
// e is { P: (1) $$
if
(
leftToken
==
lastTokenInPattern
)
{
// Patterns such as 'e is not $$', 'e is 1 or $$', and 'e is ($$' should be invalid here
// as they are incomplete patterns.
return
!(
leftToken
.
IsKind
(
SyntaxKind
.
OrKeyword
)
||
leftToken
.
IsKind
(
SyntaxKind
.
AndKeyword
)
||
leftToken
.
IsKind
(
SyntaxKind
.
NotKeyword
)
||
leftToken
.
IsKind
(
SyntaxKind
.
OpenParenToken
));
}
// We want to make sure that IsAtEndOfPattern returns true even when the user is in the middle of typing a keyword
// after a pattern.
// For example, with the keyword 'and', we want to make sure that 'e is int an$$' is still recognized as valid.
if
(
lastTokenInPattern
.
Parent
is
SingleVariableDesignationSyntax
variableDesignationSyntax
&&
originalLeftToken
.
Parent
==
variableDesignationSyntax
)
{
return
patternSyntax
is
DeclarationPatternSyntax
||
patternSyntax
is
RecursivePatternSyntax
;
}
}
// e is C.P $$
// e is int $$
if
(
leftToken
.
IsLastTokenOfNode
<
TypeSyntax
>(
out
var
typeSyntax
))
{
// If typeSyntax is part of a qualified name, we want to get the fully-qualified name so that we can
// later accurately perform the check comparing the right side of the BinaryExpressionSyntax to
// the typeSyntax.
while
(
typeSyntax
.
Parent
is
TypeSyntax
parentTypeSyntax
)
{
typeSyntax
=
parentTypeSyntax
;
}
if
(
typeSyntax
.
Parent
is
BinaryExpressionSyntax
binaryExpressionSyntax
&&
binaryExpressionSyntax
.
OperatorToken
.
IsKind
(
SyntaxKind
.
IsKeyword
)
&&
binaryExpressionSyntax
.
Right
==
typeSyntax
&&
!
typeSyntax
.
IsVar
)
{
return
true
;
}
}
// We need to include a special case for switch statement cases, as some are not currently parsed as patterns, e.g. case (1 $$
if
(
IsAtEndOfSwitchStatementPattern
(
leftToken
))
{
return
true
;
}
return
false
;
static
bool
IsAtEndOfSwitchStatementPattern
(
SyntaxToken
leftToken
)
{
var
node
=
leftToken
.
Parent
;
// Walking up the tree for expressions such as 'case (((N.C.P $$'
while
(
node
.
IsParentKind
(
SyntaxKind
.
SimpleMemberAccessExpression
))
{
node
=
node
.
Parent
;
}
// Getting rid of the extra parentheses to deal with cases such as 'case (((1 $$'
while
(
node
.
IsParentKind
(
SyntaxKind
.
ParenthesizedExpression
))
{
node
=
node
.
Parent
;
}
// case (1 $$
if
(
node
.
IsParentKind
(
SyntaxKind
.
CaseSwitchLabel
)
&&
node
.
Parent
.
IsParentKind
(
SyntaxKind
.
SwitchSection
))
{
return
true
;
}
return
false
;
}
#endif
}
private
static
SyntaxToken
FindTokenOnLeftOfNode
(
SyntaxNode
node
)
...
...
@@ -1850,7 +1976,7 @@ public static bool IsDefiniteCastTypeContext(this SyntaxTree syntaxTree, int pos
public
static
bool
IsConstantExpressionContext
(
this
SyntaxTree
syntaxTree
,
int
position
,
SyntaxToken
tokenOnLeftOfPosition
)
{
if
(
Is
PatternContext
(
syntaxTree
,
tokenOnLeftOfPosition
,
position
))
if
(
Is
AtStartOfPattern
(
syntaxTree
,
tokenOnLeftOfPosition
,
position
))
{
return
true
;
}
...
...
src/Workspaces/SharedUtilitiesAndExtensions/Workspace/Core/Extensions/ContextQuery/SyntaxContext.cs
浏览文件 @
49e35a55
...
...
@@ -35,7 +35,8 @@ internal abstract class SyntaxContext
bool
isInImportsDirective
,
bool
isWithinAsyncMethod
,
bool
isPossibleTupleContext
,
bool
isPatternContext
,
bool
isAtStartOfPattern
,
bool
isAtEndOfPattern
,
bool
isRightSideOfNumericType
,
bool
isOnArgumentListBracketOrComma
,
CancellationToken
cancellationToken
)
...
...
@@ -60,7 +61,8 @@ internal abstract class SyntaxContext
this
.
IsInImportsDirective
=
isInImportsDirective
;
this
.
IsWithinAsyncMethod
=
isWithinAsyncMethod
;
this
.
IsPossibleTupleContext
=
isPossibleTupleContext
;
this
.
IsPatternContext
=
isPatternContext
;
this
.
IsAtStartOfPattern
=
isAtStartOfPattern
;
this
.
IsAtEndOfPattern
=
isAtEndOfPattern
;
this
.
InferredTypes
=
ComputeInferredTypes
(
workspace
,
semanticModel
,
position
,
cancellationToken
);
this
.
IsRightSideOfNumericType
=
isRightSideOfNumericType
;
this
.
IsOnArgumentListBracketOrComma
=
isOnArgumentListBracketOrComma
;
...
...
@@ -92,7 +94,8 @@ internal abstract class SyntaxContext
public
bool
IsInImportsDirective
{
get
;
}
public
bool
IsWithinAsyncMethod
{
get
;
}
public
bool
IsPossibleTupleContext
{
get
;
}
public
bool
IsPatternContext
{
get
;
}
public
bool
IsAtStartOfPattern
{
get
;
}
public
bool
IsAtEndOfPattern
{
get
;
}
public
bool
IsRightSideOfNumericType
{
get
;
}
public
bool
IsOnArgumentListBracketOrComma
{
get
;
}
...
...
src/Workspaces/SharedUtilitiesAndExtensions/Workspace/VisualBasic/Extensions/ContextQuery/VisualBasicSyntaxContext.vb
浏览文件 @
49e35a55
...
...
@@ -100,7 +100,8 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.Extensions.ContextQuery
isInImportsDirective
:
=
isInImportsDirective
,
isWithinAsyncMethod
:
=
IsWithinAsyncMethod
(
targetToken
,
cancellationToken
),
isPossibleTupleContext
:
=
isPossibleTupleContext
,
isPatternContext
:
=
False
,
isAtStartOfPattern
:
=
False
,
isAtEndOfPattern
:
=
False
,
isRightSideOfNumericType
:
=
False
,
isOnArgumentListBracketOrComma
:
=
isInArgumentList
,
cancellationToken
:
=
cancellationToken
)
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录