Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
lwm1986
roslyn
提交
07984da9
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,发现更多精彩内容 >>
提交
07984da9
编写于
6月 03, 2016
作者:
N
Neal Gafter
浏览文件
操作
浏览文件
下载
差异文件
Merge pull request #11718 from gafter/master-errlambda02
Attempt type inference when there are no applicable methods
上级
c346e48d
f70ec796
变更
3
隐藏空白更改
内联
并排
Showing
3 changed file
with
220 addition
and
50 deletion
+220
-50
src/Compilers/CSharp/Portable/Binder/Binder.cs
src/Compilers/CSharp/Portable/Binder/Binder.cs
+0
-37
src/Compilers/CSharp/Portable/Binder/Semantics/OverloadResolution/OverloadResolution.cs
...Binder/Semantics/OverloadResolution/OverloadResolution.cs
+36
-11
src/Compilers/CSharp/Test/Semantic/Semantics/LambdaTests.cs
src/Compilers/CSharp/Test/Semantic/Semantics/LambdaTests.cs
+184
-2
未找到文件。
src/Compilers/CSharp/Portable/Binder/Binder.cs
浏览文件 @
07984da9
...
...
@@ -605,43 +605,6 @@ private static ThreeState ReportDiagnosticsIfObsoleteInternal(DiagnosticBag diag
return
ThreeState
.
True
;
}
internal
void
ResolveOverloads
<
TMember
>(
ImmutableArray
<
TMember
>
members
,
ImmutableArray
<
TypeSymbol
>
typeArguments
,
ImmutableArray
<
ArgumentSyntax
>
arguments
,
OverloadResolutionResult
<
TMember
>
result
,
ref
HashSet
<
DiagnosticInfo
>
useSiteDiagnostics
,
bool
allowRefOmittedArguments
)
where
TMember
:
Symbol
{
var
methodsBuilder
=
ArrayBuilder
<
TMember
>.
GetInstance
(
members
.
Length
);
methodsBuilder
.
AddRange
(
members
);
var
typeArgumentsBuilder
=
ArrayBuilder
<
TypeSymbol
>.
GetInstance
(
typeArguments
.
Length
);
typeArgumentsBuilder
.
AddRange
(
typeArguments
);
var
analyzedArguments
=
AnalyzedArguments
.
GetInstance
();
var
unusedDiagnostics
=
DiagnosticBag
.
GetInstance
();
foreach
(
var
argumentSyntax
in
arguments
)
{
BindArgumentAndName
(
analyzedArguments
,
unusedDiagnostics
,
false
,
argumentSyntax
,
allowArglist
:
false
);
}
OverloadResolution
.
MethodOrPropertyOverloadResolution
(
methodsBuilder
,
typeArgumentsBuilder
,
analyzedArguments
,
result
,
isMethodGroupConversion
:
false
,
allowRefOmittedArguments
:
allowRefOmittedArguments
,
useSiteDiagnostics
:
ref
useSiteDiagnostics
);
methodsBuilder
.
Free
();
typeArgumentsBuilder
.
Free
();
analyzedArguments
.
Free
();
unusedDiagnostics
.
Free
();
}
internal
bool
IsSymbolAccessibleConditional
(
Symbol
symbol
,
AssemblySymbol
within
,
...
...
src/Compilers/CSharp/Portable/Binder/Semantics/OverloadResolution/OverloadResolution.cs
浏览文件 @
07984da9
...
...
@@ -252,17 +252,16 @@ private static bool OverloadResolutionResultIsValid<TMember>(ArrayBuilder<Member
// Also note that less derived members are not actually removed - they are simply flagged.
ReportUseSiteDiagnostics
(
results
,
ref
useSiteDiagnostics
);
// SPEC: If the resulting set of candidate methods is empty, then further processing along the following steps are abandoned,
// SPEC: and instead an attempt is made to process the invocation as an extension method invocation. If this fails, then no
// SPEC: applicable methods exist, and a binding-time error occurs.
// SPEC: If the resulting set of candidate methods is empty, then further processing along the following steps are abandoned,
// SPEC: and instead an attempt is made to process the invocation as an extension method invocation. If this fails, then no
// SPEC: applicable methods exist, and a binding-time error occurs.
if
(
RemainingCandidatesCount
(
results
)
==
0
)
{
// UNDONE: Extension methods!
return
;
}
// SPEC: The best method of the set of candidate methods is identified. If a single best method cannot be identified,
// SPEC: the method invocation is ambiguous, and a binding-time error occurs.
// SPEC: The best method of the set of candidate methods is identified. If a single best method cannot be identified,
// SPEC: the method invocation is ambiguous, and a binding-time error occurs.
RemoveWorseMembers
(
results
,
arguments
,
ref
useSiteDiagnostics
);
...
...
@@ -494,7 +493,7 @@ private MemberAnalysisResult IsConstructorApplicableInExpandedForm(MethodSymbol
// Second, we need to determine if the method is applicable in its normal form or its expanded form.
var
normalResult
=
(
allowUnexpandedForm
||
!
IsValidParams
(
leastOverriddenMember
))
?
IsMemberApplicableInNormalForm
(
member
,
leastOverriddenMember
,
typeArguments
,
arguments
,
isMethodGroupConversion
,
allowRefOmittedArguments
,
inferWithDynamic
,
ref
useSiteDiagnostics
)
?
IsMemberApplicableInNormalForm
(
member
,
leastOverriddenMember
,
typeArguments
,
arguments
,
isMethodGroupConversion
,
allowRefOmittedArguments
,
inferWithDynamic
,
ref
useSiteDiagnostics
,
completeResults
:
completeResults
)
:
default
(
MemberResolutionResult
<
TMember
>);
var
result
=
normalResult
;
...
...
@@ -2511,7 +2510,8 @@ private RefKind GetEffectiveParameterRefKind(ParameterSymbol parameter, RefKind
bool
isMethodGroupConversion
,
bool
allowRefOmittedArguments
,
bool
inferWithDynamic
,
ref
HashSet
<
DiagnosticInfo
>
useSiteDiagnostics
)
ref
HashSet
<
DiagnosticInfo
>
useSiteDiagnostics
,
bool
completeResults
=
false
)
where
TMember
:
Symbol
{
// AnalyzeArguments matches arguments to parameter names and positions.
...
...
@@ -2519,7 +2519,13 @@ private RefKind GetEffectiveParameterRefKind(ParameterSymbol parameter, RefKind
var
argumentAnalysis
=
AnalyzeArguments
(
member
,
arguments
,
isMethodGroupConversion
,
expanded
:
false
);
if
(!
argumentAnalysis
.
IsValid
)
{
return
new
MemberResolutionResult
<
TMember
>(
member
,
leastOverriddenMember
,
MemberAnalysisResult
.
ArgumentParameterMismatch
(
argumentAnalysis
));
// When we are producing more complete results, and a required parameter is missing, we push on
// to type inference so that lambda arguments can be bound to their delegate-typed parameters,
// thus improving the API and intellisense experience.
if
(!
completeResults
||
argumentAnalysis
.
Kind
!=
ArgumentAnalysisResultKind
.
RequiredParameterMissing
)
{
return
new
MemberResolutionResult
<
TMember
>(
member
,
leastOverriddenMember
,
MemberAnalysisResult
.
ArgumentParameterMismatch
(
argumentAnalysis
));
}
}
// Check after argument analysis, but before more complicated type inference and argument type validation.
...
...
@@ -2552,12 +2558,21 @@ private RefKind GetEffectiveParameterRefKind(ParameterSymbol parameter, RefKind
// The member passed to the following call is returned in the result (possibly a constructed version of it).
// The applicability is checked based on effective parameters passed in.
return
IsApplicable
(
var
applicableResult
=
IsApplicable
(
member
,
leastOverriddenMember
,
typeArguments
,
arguments
,
originalEffectiveParameters
,
constructedEffectiveParameters
,
argumentAnalysis
.
ArgsToParamsOpt
,
hasAnyRefOmittedArgument
,
ref
useSiteDiagnostics
,
inferWithDynamic
);
// If we were producing complete results and had missing arguments, we pushed on in order to call IsApplicable for
// type inference and lambda binding. In that case we still need to return the argument mismatch failure here.
if
(
completeResults
&&
!
argumentAnalysis
.
IsValid
)
{
return
new
MemberResolutionResult
<
TMember
>(
member
,
leastOverriddenMember
,
MemberAnalysisResult
.
ArgumentParameterMismatch
(
argumentAnalysis
));
}
return
applicableResult
;
}
private
MemberResolutionResult
<
TMember
>
IsMemberApplicableInExpandedForm
<
TMember
>(
...
...
@@ -2802,7 +2817,17 @@ private RefKind GetEffectiveParameterRefKind(ParameterSymbol parameter, RefKind
// We add a "virtual parameter" for the __arglist.
int
paramCount
=
parameters
.
ParameterTypes
.
Length
+
(
isVararg
?
1
:
0
);
Debug
.
Assert
(
paramCount
==
arguments
.
Arguments
.
Count
);
if
(
arguments
.
Arguments
.
Count
<
paramCount
)
{
// For improved error recovery, we perform type inference even when the argument
// list is of the wrong length. The caller is expected to detect and handle that,
// treating the method as inapplicable.
paramCount
=
arguments
.
Arguments
.
Count
;
}
else
{
Debug
.
Assert
(
paramCount
==
arguments
.
Arguments
.
Count
);
}
// For each argument in A, the parameter passing mode of the argument (i.e., value, ref, or out) is
// identical to the parameter passing mode of the corresponding parameter, and
...
...
src/Compilers/CSharp/Test/Semantic/Semantics/LambdaTests.cs
浏览文件 @
07984da9
...
...
@@ -1768,8 +1768,7 @@ public class MyArgumentType
// (6,57): error CS1002: ; expected
// var handler = new MyDelegateType((s, e) => { e. });
Diagnostic
(
ErrorCode
.
ERR_SemicolonExpected
,
"}"
).
WithLocation
(
6
,
57
)
)
;
);
var
tree
=
compilation
.
SyntaxTrees
[
0
];
var
sm
=
compilation
.
GetSemanticModel
(
tree
);
var
lambda
=
tree
.
GetCompilationUnitRoot
().
DescendantNodes
().
OfType
<
LambdaExpressionSyntax
>().
Single
();
...
...
@@ -1780,6 +1779,189 @@ public class MyArgumentType
Assert
.
Equal
(
TypeKind
.
Class
,
typeInfo
.
Type
.
TypeKind
);
Assert
.
NotEmpty
(
typeInfo
.
Type
.
GetMembers
(
"SomePublicMember"
));
}
[
Fact
]
[
WorkItem
(
11053
,
"https://github.com/dotnet/roslyn/issues/11053"
)]
[
WorkItem
(
11358
,
"https://github.com/dotnet/roslyn/issues/11358"
)]
public
void
TestLambdaWithError07
()
{
var
source
=
@"using System;
using System.Collections.Generic;
public static class Program
{
public static void Main()
{
var parameter = new List<string>();
var result = parameter.FirstOrDefault(x => x. );
}
}
public static class Enumerable
{
public static TSource FirstOrDefault<TSource>(this IEnumerable<TSource> source, TSource defaultValue)
{
return default(TSource);
}
public static TSource FirstOrDefault<TSource>(this IEnumerable<TSource> source, Func<TSource, bool> predicate, TSource defaultValue)
{
return default(TSource);
}
}"
;
var
compilation
=
CreateCompilationWithMscorlibAndSystemCore
(
source
).
VerifyDiagnostics
(
// (9,55): error CS1001: Identifier expected
// var result = parameter.FirstOrDefault(x => x. );
Diagnostic
(
ErrorCode
.
ERR_IdentifierExpected
,
")"
).
WithLocation
(
9
,
55
)
);
var
tree
=
compilation
.
SyntaxTrees
[
0
];
var
sm
=
compilation
.
GetSemanticModel
(
tree
);
var
lambda
=
tree
.
GetCompilationUnitRoot
().
DescendantNodes
().
OfType
<
LambdaExpressionSyntax
>().
Single
();
var
eReference
=
lambda
.
Body
.
DescendantNodes
().
OfType
<
IdentifierNameSyntax
>().
First
();
Assert
.
Equal
(
"x"
,
eReference
.
ToString
());
var
typeInfo
=
sm
.
GetTypeInfo
(
eReference
);
Assert
.
Equal
(
TypeKind
.
Class
,
typeInfo
.
Type
.
TypeKind
);
Assert
.
Equal
(
"String"
,
typeInfo
.
Type
.
Name
);
Assert
.
NotEmpty
(
typeInfo
.
Type
.
GetMembers
(
"Replace"
));
}
[
Fact
]
[
WorkItem
(
11053
,
"https://github.com/dotnet/roslyn/issues/11053"
)]
[
WorkItem
(
11358
,
"https://github.com/dotnet/roslyn/issues/11358"
)]
public
void
TestLambdaWithError08
()
{
var
source
=
@"using System;
using System.Collections.Generic;
public static class Program
{
public static void Main()
{
var parameter = new List<string>();
var result = parameter.FirstOrDefault(x => x. );
}
}
public static class Enumerable
{
public static TSource FirstOrDefault<TSource>(this IEnumerable<TSource> source, params TSource[] defaultValue)
{
return default(TSource);
}
public static TSource FirstOrDefault<TSource>(this IEnumerable<TSource> source, Func<TSource, bool> predicate, params TSource[] defaultValue)
{
return default(TSource);
}
}"
;
var
compilation
=
CreateCompilationWithMscorlibAndSystemCore
(
source
).
VerifyDiagnostics
(
// (9,55): error CS1001: Identifier expected
// var result = parameter.FirstOrDefault(x => x. );
Diagnostic
(
ErrorCode
.
ERR_IdentifierExpected
,
")"
).
WithLocation
(
9
,
55
)
);
var
tree
=
compilation
.
SyntaxTrees
[
0
];
var
sm
=
compilation
.
GetSemanticModel
(
tree
);
var
lambda
=
tree
.
GetCompilationUnitRoot
().
DescendantNodes
().
OfType
<
LambdaExpressionSyntax
>().
Single
();
var
eReference
=
lambda
.
Body
.
DescendantNodes
().
OfType
<
IdentifierNameSyntax
>().
First
();
Assert
.
Equal
(
"x"
,
eReference
.
ToString
());
var
typeInfo
=
sm
.
GetTypeInfo
(
eReference
);
Assert
.
Equal
(
TypeKind
.
Class
,
typeInfo
.
Type
.
TypeKind
);
Assert
.
Equal
(
"String"
,
typeInfo
.
Type
.
Name
);
Assert
.
NotEmpty
(
typeInfo
.
Type
.
GetMembers
(
"Replace"
));
}
[
Fact
]
[
WorkItem
(
11053
,
"https://github.com/dotnet/roslyn/issues/11053"
)]
[
WorkItem
(
11358
,
"https://github.com/dotnet/roslyn/issues/11358"
)]
public
void
TestLambdaWithError09
()
{
var
source
=
@"using System;
public static class Program
{
public static void Main()
{
var parameter = new MyList<string>();
var result = parameter.FirstOrDefault(x => x. );
}
}
public class MyList<TSource>
{
public TSource FirstOrDefault(TSource defaultValue)
{
return default(TSource);
}
public TSource FirstOrDefault(Func<TSource, bool> predicate, TSource defaultValue)
{
return default(TSource);
}
}
"
;
var
compilation
=
CreateCompilationWithMscorlibAndSystemCore
(
source
).
VerifyDiagnostics
(
// (8,55): error CS1001: Identifier expected
// var result = parameter.FirstOrDefault(x => x. );
Diagnostic
(
ErrorCode
.
ERR_IdentifierExpected
,
")"
).
WithLocation
(
8
,
55
)
);
var
tree
=
compilation
.
SyntaxTrees
[
0
];
var
sm
=
compilation
.
GetSemanticModel
(
tree
);
var
lambda
=
tree
.
GetCompilationUnitRoot
().
DescendantNodes
().
OfType
<
LambdaExpressionSyntax
>().
Single
();
var
eReference
=
lambda
.
Body
.
DescendantNodes
().
OfType
<
IdentifierNameSyntax
>().
First
();
Assert
.
Equal
(
"x"
,
eReference
.
ToString
());
var
typeInfo
=
sm
.
GetTypeInfo
(
eReference
);
Assert
.
Equal
(
TypeKind
.
Class
,
typeInfo
.
Type
.
TypeKind
);
Assert
.
Equal
(
"String"
,
typeInfo
.
Type
.
Name
);
Assert
.
NotEmpty
(
typeInfo
.
Type
.
GetMembers
(
"Replace"
));
}
[
Fact
]
[
WorkItem
(
11053
,
"https://github.com/dotnet/roslyn/issues/11053"
)]
[
WorkItem
(
11358
,
"https://github.com/dotnet/roslyn/issues/11358"
)]
public
void
TestLambdaWithError10
()
{
var
source
=
@"using System;
public static class Program
{
public static void Main()
{
var parameter = new MyList<string>();
var result = parameter.FirstOrDefault(x => x. );
}
}
public class MyList<TSource>
{
public TSource FirstOrDefault(params TSource[] defaultValue)
{
return default(TSource);
}
public TSource FirstOrDefault(Func<TSource, bool> predicate, params TSource[] defaultValue)
{
return default(TSource);
}
}
"
;
var
compilation
=
CreateCompilationWithMscorlibAndSystemCore
(
source
).
VerifyDiagnostics
(
// (8,55): error CS1001: Identifier expected
// var result = parameter.FirstOrDefault(x => x. );
Diagnostic
(
ErrorCode
.
ERR_IdentifierExpected
,
")"
).
WithLocation
(
8
,
55
)
);
var
tree
=
compilation
.
SyntaxTrees
[
0
];
var
sm
=
compilation
.
GetSemanticModel
(
tree
);
var
lambda
=
tree
.
GetCompilationUnitRoot
().
DescendantNodes
().
OfType
<
LambdaExpressionSyntax
>().
Single
();
var
eReference
=
lambda
.
Body
.
DescendantNodes
().
OfType
<
IdentifierNameSyntax
>().
First
();
Assert
.
Equal
(
"x"
,
eReference
.
ToString
());
var
typeInfo
=
sm
.
GetTypeInfo
(
eReference
);
Assert
.
Equal
(
TypeKind
.
Class
,
typeInfo
.
Type
.
TypeKind
);
Assert
.
Equal
(
"String"
,
typeInfo
.
Type
.
Name
);
Assert
.
NotEmpty
(
typeInfo
.
Type
.
GetMembers
(
"Replace"
));
}
}
}
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录