Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
lwm1986
roslyn
提交
567d12f6
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,发现更多精彩内容 >>
提交
567d12f6
编写于
6月 06, 2016
作者:
G
gafter
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Improved error recovery for lambdas in a call with extra arguments.
Fixes #557, #5498
上级
b6e3176e
变更
3
隐藏空白更改
内联
并排
Showing
3 changed file
with
77 addition
and
14 deletion
+77
-14
src/Compilers/CSharp/Portable/Binder/Semantics/OverloadResolution/MethodTypeInference.cs
...inder/Semantics/OverloadResolution/MethodTypeInference.cs
+9
-4
src/Compilers/CSharp/Portable/Binder/Semantics/OverloadResolution/OverloadResolution.cs
...Binder/Semantics/OverloadResolution/OverloadResolution.cs
+11
-10
src/Compilers/CSharp/Test/Semantic/Semantics/LambdaTests.cs
src/Compilers/CSharp/Test/Semantic/Semantics/LambdaTests.cs
+57
-0
未找到文件。
src/Compilers/CSharp/Portable/Binder/Semantics/OverloadResolution/MethodTypeInference.cs
浏览文件 @
567d12f6
...
@@ -97,6 +97,12 @@ private enum Dependency
...
@@ -97,6 +97,12 @@ private enum Dependency
private
Dependency
[,]
_dependencies
;
// Initialized lazily
private
Dependency
[,]
_dependencies
;
// Initialized lazily
private
bool
_dependenciesDirty
;
private
bool
_dependenciesDirty
;
/// <summary>
/// For error recovery, we allow a mismatch between the number of arguments and parameters
/// during type inference. This sometimes enables inferring the type for a lambda parameter.
/// </summary>
private
int
Length
=>
System
.
Math
.
Min
(
_arguments
.
Length
,
_formalParameterTypes
.
Length
);
public
static
MethodTypeInferenceResult
Infer
(
public
static
MethodTypeInferenceResult
Infer
(
Binder
binder
,
Binder
binder
,
ImmutableArray
<
TypeParameterSymbol
>
methodTypeParameters
,
ImmutableArray
<
TypeParameterSymbol
>
methodTypeParameters
,
...
@@ -524,14 +530,13 @@ private void InferTypeArgsFirstPhase(Binder binder, ref HashSet<DiagnosticInfo>
...
@@ -524,14 +530,13 @@ private void InferTypeArgsFirstPhase(Binder binder, ref HashSet<DiagnosticInfo>
{
{
Debug
.
Assert
(!
_formalParameterTypes
.
IsDefault
);
Debug
.
Assert
(!
_formalParameterTypes
.
IsDefault
);
Debug
.
Assert
(!
_arguments
.
IsDefault
);
Debug
.
Assert
(!
_arguments
.
IsDefault
);
Debug
.
Assert
(
_arguments
.
Length
==
_formalParameterTypes
.
Length
);
// We expect that we have been handed a list of arguments and a list of the
// We expect that we have been handed a list of arguments and a list of the
// formal parameter types they correspond to; all the details about named and
// formal parameter types they correspond to; all the details about named and
// optional parameters have already been dealt with.
// optional parameters have already been dealt with.
// SPEC: For each of the method arguments Ei:
// SPEC: For each of the method arguments Ei:
for
(
int
arg
=
0
;
arg
<
_arguments
.
L
ength
;
arg
++)
for
(
int
arg
=
0
,
length
=
this
.
Length
;
arg
<
l
ength
;
arg
++)
{
{
var
argument
=
_arguments
[
arg
];
var
argument
=
_arguments
[
arg
];
...
@@ -795,7 +800,7 @@ private void MakeOutputTypeInferences(Binder binder, ref HashSet<DiagnosticInfo>
...
@@ -795,7 +800,7 @@ private void MakeOutputTypeInferences(Binder binder, ref HashSet<DiagnosticInfo>
// SPEC: where the output types contain unfixed type parameters but the input
// SPEC: where the output types contain unfixed type parameters but the input
// SPEC: types do not, an output type inference is made from Ei to Ti.
// SPEC: types do not, an output type inference is made from Ei to Ti.
for
(
int
arg
=
0
;
arg
<
_arguments
.
L
ength
;
arg
++)
for
(
int
arg
=
0
,
length
=
this
.
Length
;
arg
<
l
ength
;
arg
++)
{
{
var
formalType
=
_formalParameterTypes
[
arg
];
var
formalType
=
_formalParameterTypes
[
arg
];
var
argument
=
_arguments
[
arg
];
var
argument
=
_arguments
[
arg
];
...
@@ -1067,7 +1072,7 @@ private bool DependsDirectlyOn(int iParam, int jParam)
...
@@ -1067,7 +1072,7 @@ private bool DependsDirectlyOn(int iParam, int jParam)
Debug
.
Assert
(
IsUnfixed
(
iParam
));
Debug
.
Assert
(
IsUnfixed
(
iParam
));
Debug
.
Assert
(
IsUnfixed
(
jParam
));
Debug
.
Assert
(
IsUnfixed
(
jParam
));
for
(
int
iArg
=
0
;
iArg
<
_arguments
.
L
ength
;
iArg
++)
for
(
int
iArg
=
0
,
length
=
this
.
Length
;
iArg
<
l
ength
;
iArg
++)
{
{
var
formalParameterType
=
_formalParameterTypes
[
iArg
];
var
formalParameterType
=
_formalParameterTypes
[
iArg
];
var
argument
=
_arguments
[
iArg
];
var
argument
=
_arguments
[
iArg
];
...
...
src/Compilers/CSharp/Portable/Binder/Semantics/OverloadResolution/OverloadResolution.cs
浏览文件 @
567d12f6
...
@@ -2407,7 +2407,7 @@ internal EffectiveParameters(ImmutableArray<TypeSymbol> types, ImmutableArray<Re
...
@@ -2407,7 +2407,7 @@ internal EffectiveParameters(ImmutableArray<TypeSymbol> types, ImmutableArray<Re
{
{
int
parm
=
argToParamMap
.
IsDefault
?
arg
:
argToParamMap
[
arg
];
int
parm
=
argToParamMap
.
IsDefault
?
arg
:
argToParamMap
[
arg
];
// If this is the __arglist parameter, just skip it.
// If this is the __arglist parameter, just skip it.
if
(
parm
=
=
parameters
.
Length
)
if
(
parm
>
=
parameters
.
Length
)
{
{
continue
;
continue
;
}
}
...
@@ -2519,12 +2519,17 @@ private RefKind GetEffectiveParameterRefKind(ParameterSymbol parameter, RefKind
...
@@ -2519,12 +2519,17 @@ private RefKind GetEffectiveParameterRefKind(ParameterSymbol parameter, RefKind
var
argumentAnalysis
=
AnalyzeArguments
(
member
,
arguments
,
isMethodGroupConversion
,
expanded
:
false
);
var
argumentAnalysis
=
AnalyzeArguments
(
member
,
arguments
,
isMethodGroupConversion
,
expanded
:
false
);
if
(!
argumentAnalysis
.
IsValid
)
if
(!
argumentAnalysis
.
IsValid
)
{
{
// When we are producing more complete results, and a required parameter is missing, we push on
switch
(
argumentAnalysis
.
Kind
)
// 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
));
case
ArgumentAnalysisResultKind
.
RequiredParameterMissing
:
case
ArgumentAnalysisResultKind
.
NoCorrespondingParameter
:
if
(!
completeResults
)
goto
default
;
// When we are producing more complete results, and we have the wrong number of arguments, we push on
// through type inference so that lambda arguments can be bound to their delegate-typed parameters,
// thus improving the API and intellisense experience.
break
;
default
:
return
new
MemberResolutionResult
<
TMember
>(
member
,
leastOverriddenMember
,
MemberAnalysisResult
.
ArgumentParameterMismatch
(
argumentAnalysis
));
}
}
}
}
...
@@ -2824,10 +2829,6 @@ private RefKind GetEffectiveParameterRefKind(ParameterSymbol parameter, RefKind
...
@@ -2824,10 +2829,6 @@ private RefKind GetEffectiveParameterRefKind(ParameterSymbol parameter, RefKind
// treating the method as inapplicable.
// treating the method as inapplicable.
paramCount
=
arguments
.
Arguments
.
Count
;
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
// 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
// identical to the parameter passing mode of the corresponding parameter, and
...
...
src/Compilers/CSharp/Test/Semantic/Semantics/LambdaTests.cs
浏览文件 @
567d12f6
...
@@ -1963,5 +1963,62 @@ public TSource FirstOrDefault(Func<TSource, bool> predicate, params TSource[] de
...
@@ -1963,5 +1963,62 @@ public TSource FirstOrDefault(Func<TSource, bool> predicate, params TSource[] de
Assert
.
Equal
(
"String"
,
typeInfo
.
Type
.
Name
);
Assert
.
Equal
(
"String"
,
typeInfo
.
Type
.
Name
);
Assert
.
NotEmpty
(
typeInfo
.
Type
.
GetMembers
(
"Replace"
));
Assert
.
NotEmpty
(
typeInfo
.
Type
.
GetMembers
(
"Replace"
));
}
}
[
Fact
]
[
WorkItem
(
557
,
"https://github.com/dotnet/roslyn/issues/557"
)]
public
void
TestLambdaWithError11
()
{
var
source
=
@"using System.Linq;
public static class Program
{
public static void Main()
{
var x = new {
X = """".Select(c => c.
Y = 0,
};
}
}
"
;
var
compilation
=
CreateCompilationWithMscorlibAndSystemCore
(
source
);
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
(
"c"
,
eReference
.
ToString
());
var
typeInfo
=
sm
.
GetTypeInfo
(
eReference
);
Assert
.
Equal
(
TypeKind
.
Struct
,
typeInfo
.
Type
.
TypeKind
);
Assert
.
Equal
(
"Char"
,
typeInfo
.
Type
.
Name
);
Assert
.
NotEmpty
(
typeInfo
.
Type
.
GetMembers
(
"IsHighSurrogate"
));
// check it is the char we know and love
}
[
Fact
]
[
WorkItem
(
5498
,
"https://github.com/dotnet/roslyn/issues/5498"
)]
public
void
TestLambdaWithError12
()
{
var
source
=
@"using System.Linq;
class Program
{
static void Main(string[] args)
{
var z = args.Select(a => a.
var foo =
}
}"
;
var
compilation
=
CreateCompilationWithMscorlibAndSystemCore
(
source
);
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
(
"a"
,
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.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录