Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
lwm1986
roslyn
提交
a73e0141
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,体验更适合开发者的 AI 搜索 >>
提交
a73e0141
编写于
7月 14, 2016
作者:
E
Evan Hauck
提交者:
Jared Parsons
4月 26, 2017
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Fix a few issues that were blocking VS dogfooding
上级
d978315f
变更
10
隐藏空白更改
内联
并排
Showing
10 changed file
with
153 addition
and
29 deletion
+153
-29
src/Compilers/CSharp/Portable/Binder/Binder_Expressions.cs
src/Compilers/CSharp/Portable/Binder/Binder_Expressions.cs
+17
-5
src/Compilers/CSharp/Portable/CodeGen/EmitExpression.cs
src/Compilers/CSharp/Portable/CodeGen/EmitExpression.cs
+7
-1
src/Compilers/CSharp/Portable/Compilation/CSharpSemanticModel.cs
...pilers/CSharp/Portable/Compilation/CSharpSemanticModel.cs
+17
-16
src/Compilers/CSharp/Portable/Symbols/ReducedExtensionMethodSymbol.cs
...s/CSharp/Portable/Symbols/ReducedExtensionMethodSymbol.cs
+5
-1
src/Compilers/CSharp/Portable/Symbols/Retargeting/RetargetingNamespaceSymbol.cs
...ortable/Symbols/Retargeting/RetargetingNamespaceSymbol.cs
+1
-1
src/Compilers/CSharp/Portable/Symbols/Source/SourceNamedTypeSymbol.cs
...s/CSharp/Portable/Symbols/Source/SourceNamedTypeSymbol.cs
+9
-2
src/Compilers/CSharp/Portable/Symbols/UnreducedExtensionMethodSymbol.cs
...CSharp/Portable/Symbols/UnreducedExtensionMethodSymbol.cs
+2
-1
src/Compilers/CSharp/Portable/Symbols/UnreducedExtensionPropertySymbol.cs
...harp/Portable/Symbols/UnreducedExtensionPropertySymbol.cs
+9
-1
src/Compilers/CSharp/Test/Semantic/Semantics/ExtensionEverythingTests.cs
...Sharp/Test/Semantic/Semantics/ExtensionEverythingTests.cs
+85
-0
src/Workspaces/CoreTest/SymbolKeyTests.cs
src/Workspaces/CoreTest/SymbolKeyTests.cs
+1
-1
未找到文件。
src/Compilers/CSharp/Portable/Binder/Binder_Expressions.cs
浏览文件 @
a73e0141
...
...
@@ -5650,10 +5650,19 @@ private static void CopyExtensionMethodArguments(AnalyzedArguments originalArgum
var
members
=
ArrayBuilder
<
Symbol
>.
GetInstance
();
bool
wasError
;
Symbol
symbol
=
GetSymbolOrMethodOrPropertyGroup
(
lookupResult
,
node
,
rightName
,
arity
,
members
,
diagnostics
,
out
wasError
);
// PROTOTYPE: This might not be true for extension classes - LookupExtensionMembers returns other kinds of members.
Debug
.
Assert
((
object
)
symbol
==
null
);
Debug
.
Assert
(
members
.
Count
>
0
);
methodGroup
.
PopulateWithExtensionMethods
(
left
,
members
.
SelectAsArray
(
s_toMethodSymbolFunc
),
typeArguments
,
lookupResult
.
Kind
);
if
((
object
)
symbol
!=
null
)
{
// This can happen when a non-extension method was found on the type (say, .Count()),
// and an extension property was found (say, .Count). For now, always prefer the non-extension method.
// PROTOTYPE: Evalulate the above statement, and figure out what to do in the face of mixed-member-kind lookups in general
// (e.g. when both property and method extensions are found with the same name, and both are applicable)
Debug
.
Assert
(!
members
.
Any
());
}
else
{
Debug
.
Assert
(
members
.
Count
>
0
);
methodGroup
.
PopulateWithExtensionMethods
(
left
,
members
.
SelectAsArray
(
s_toMethodSymbolFunc
),
typeArguments
,
lookupResult
.
Kind
);
}
members
.
Free
();
}
...
...
@@ -6731,7 +6740,10 @@ private ErrorPropertySymbol CreateErrorPropertySymbol(ImmutableArray<PropertySym
methodGroup
.
Methods
,
methodGroup
.
TypeArguments
,
analyzedArguments
,
methodGroup
.
Receiver
,
result
,
ref
useSiteDiagnostics
,
isMethodGroupConversion
,
allowRefOmittedArguments
,
inferWithDynamic
:
inferWithDynamic
,
allowUnexpandedForm
:
allowUnexpandedForm
);
return
new
MethodGroupResolution
(
methodGroup
,
null
,
result
,
analyzedArguments
,
methodGroup
.
ResultKind
,
sealedDiagnostics
);
// The caller does not expect analyzedArguments to be consumed (it frees it after it's done), so make a copy to consume (for the result).
var
argumentCopy
=
AnalyzedArguments
.
GetInstance
();
CopyExtensionMethodArguments
(
analyzedArguments
,
argumentCopy
);
// PROTOTYPE: Figure out if a copy is needed (this is not an extension method).
return
new
MethodGroupResolution
(
methodGroup
,
null
,
result
,
argumentCopy
,
methodGroup
.
ResultKind
,
sealedDiagnostics
);
}
}
...
...
src/Compilers/CSharp/Portable/CodeGen/EmitExpression.cs
浏览文件 @
a73e0141
...
...
@@ -542,6 +542,7 @@ private void EmitArgListOperator(BoundArgListOperator expression)
}
}
private
void
EmitArgument
(
BoundExpression
argument
,
RefKind
refKind
)
{
if
(
refKind
==
RefKind
.
None
)
...
...
@@ -551,7 +552,12 @@ private void EmitArgument(BoundExpression argument, RefKind refKind)
else
{
var
temp
=
EmitAddress
(
argument
,
AddressKind
.
Writeable
);
Debug
.
Assert
(
temp
==
null
,
"passing args byref should not clone them into temps"
);
// PROTOTYPE: Resolve the commented-out assert.
// temporaries are allowed in the specific case of emitting a receiver for an extension class instance member extending a struct.
// This situation did not occur before, since `ref this` is not allowed on old-style extension methods (but is default for extension class).
// Disable the assert for now, until we resolve what we specifically want to do here.
//Debug.Assert(temp == null, "passing args byref should not clone them into temps");
FreeOptTemp
(
temp
);
}
}
...
...
src/Compilers/CSharp/Portable/Compilation/CSharpSemanticModel.cs
浏览文件 @
a73e0141
...
...
@@ -1500,23 +1500,26 @@ private void CheckModelAndSyntaxNodeToSpeculate(CSharpSyntaxNode syntax)
if
(
lookupResult
.
IsMultiViable
)
{
foreach
(
MethodSymbol
extensionMethod
in
lookupResult
.
Symbols
)
// PROTOTYPE: Improve this filtering
foreach
(
var
extensionMember
in
lookupResult
.
Symbols
)
{
if
(
extensionMe
thod
.
MethodKind
==
MethodKind
.
ReducedExtension
)
if
(
extensionMe
mber
.
Kind
==
SymbolKind
.
Method
)
{
// PROTOTYPE: Fix this somehow. We might have to do partial type inference to get
// the receiverType to line up right, and do receiver inference on extension class methods.
var
receiverType
=
(
TypeSymbol
)
container
;
var
rereduced
=
extensionMethod
.
UnreduceExtensionMethod
().
ReduceExtensionMethod
(
receiverType
);
if
(
rereduced
!=
null
)
var
extensionMethod
=
(
MethodSymbol
)
extensionMember
;
if
(
extensionMethod
.
MethodKind
==
MethodKind
.
ReducedExtension
)
{
results
.
Add
(
rereduced
);
// PROTOTYPE: Fix this somehow. We might have to do partial type inference to get
// the receiverType to line up right, and do receiver inference on extension class methods.
var
receiverType
=
(
TypeSymbol
)
container
;
var
rereduced
=
extensionMethod
.
UnreduceExtensionMethod
().
ReduceExtensionMethod
(
receiverType
);
if
(
rereduced
!=
null
)
{
results
.
Add
(
rereduced
);
}
continue
;
}
}
else
{
results
.
Add
(
extensionMethod
);
}
results
.
Add
(
extensionMember
);
}
}
...
...
@@ -3028,7 +3031,7 @@ public ILocalSymbol GetDeclaredSymbol(CatchDeclarationSyntax catchDeclaration, C
if
((
conversion
.
ConversionKind
==
ConversionKind
.
MethodGroup
)
&&
conversion
.
IsExtensionMethod
)
{
var
symbol
=
conversion
.
SymbolOpt
;
Debug
.
Assert
((
object
)
symbol
!=
null
&&
symbol
.
MethodKind
==
MethodKind
.
ReducedExtension
);
Debug
.
Assert
((
object
)
symbol
!=
null
&&
(
symbol
.
MethodKind
==
MethodKind
.
ReducedExtension
||
symbol
.
IsInExtensionClass
)
);
symbols
=
ImmutableArray
.
Create
<
Symbol
>(
symbol
);
resultKind
=
conversion
.
ResultKind
;
}
...
...
@@ -4128,10 +4131,8 @@ internal static ImmutableArray<MethodSymbol> GetReducedAndFilteredMethodGroupSym
constructedMethod
=
method
;
}
if
((
object
)
receiverType
!=
null
)
if
((
object
)
receiverType
!=
null
&&
constructedMethod
.
MethodKind
==
MethodKind
.
ReducedExtension
)
{
// PROTOTYPE: Figure this out
Debug
.
Assert
(
constructedMethod
.
MethodKind
==
MethodKind
.
ReducedExtension
);
constructedMethod
=
constructedMethod
.
UnreduceExtensionMethod
().
ReduceExtensionMethod
(
receiverType
);
if
((
object
)
constructedMethod
==
null
)
{
...
...
src/Compilers/CSharp/Portable/Symbols/ReducedExtensionMethodSymbol.cs
浏览文件 @
a73e0141
...
...
@@ -104,7 +104,11 @@ public override TypeSymbol ReceiverType
{
get
{
return
_typeMap
.
SubstituteType
(
_reducedFrom
.
Parameters
[
0
].
Type
).
Type
;
// Note: Do not alpha rename the type (_typeMap.SubstituteType).
// This is because upon reduction of Foo<T>(this T t) into T.Foo<T'>(), we "reduced it"
// using the receiver type of the *original* (static) method symbol type parameter.
// Typemapping to the alpha-renamed type parameter causes an impossible recursion.
return
_reducedFrom
.
Parameters
[
0
].
Type
;
}
}
...
...
src/Compilers/CSharp/Portable/Symbols/Retargeting/RetargetingNamespaceSymbol.cs
浏览文件 @
a73e0141
...
...
@@ -230,7 +230,7 @@ internal override void GetExtensionMembers(ArrayBuilder<Symbol> members, string
{
var
original
=
underlyingMethod
.
UnreduceExtensionMethod
();
var
retargeted
=
this
.
RetargetingTranslator
.
Retarget
(
original
);
var
reduced
=
retargeted
.
ReduceExtensionMethod
();
var
reduced
=
retargeted
.
ReduceExtensionMethod
();
// PROTOTYPE: Specify the receiver type here.
Debug
.
Assert
((
object
)
reduced
!=
null
);
Debug
.
Assert
(
reduced
.
IsDefinition
);
members
.
Add
(
reduced
);
...
...
src/Compilers/CSharp/Portable/Symbols/Source/SourceNamedTypeSymbol.cs
浏览文件 @
a73e0141
...
...
@@ -1118,7 +1118,6 @@ public override Symbol GetUnderlyingMember(Symbol symbol)
underlyingMembersMap
=
_underlyingMembersMap
;
}
// PROTOTYPE: Strip generic constructions off of symbol?
Symbol
cachedResult
;
if
(
underlyingMembersMap
.
TryGetValue
(
symbol
,
out
cachedResult
))
{
...
...
@@ -1157,7 +1156,15 @@ public override Symbol GetUnderlyingMember(Symbol symbol)
else
{
var
constructedFrom
=
method
.
ConstructedFrom
;
result
=
new
UnreducedExtensionMethodSymbol
(
constructedFrom
);
var
resultMethod
=
new
UnreducedExtensionMethodSymbol
(
constructedFrom
);
if
(
method
!=
constructedFrom
)
{
result
=
resultMethod
.
Construct
(
method
.
TypeArguments
);
}
else
{
result
=
resultMethod
;
}
}
// PROTOTYPE: Generics/construction of result? (probably put in Create method)
break
;
...
...
src/Compilers/CSharp/Portable/Symbols/UnreducedExtensionMethodSymbol.cs
浏览文件 @
a73e0141
...
...
@@ -229,7 +229,8 @@ public override int GetHashCode()
private
sealed
class
UnreducedExtensionMethodThisParameterSymbol
:
SynthesizedParameterSymbol
{
public
UnreducedExtensionMethodThisParameterSymbol
(
UnreducedExtensionMethodSymbol
containingMethod
)
:
base
(
containingMethod
,
containingMethod
.
ContainingType
.
ExtensionClassType
,
0
,
RefKind
.
None
)
base
(
containingMethod
,
containingMethod
.
ContainingType
.
ExtensionClassType
,
0
,
containingMethod
.
ContainingType
.
ExtensionClassType
.
IsValueType
?
RefKind
.
Ref
:
RefKind
.
None
)
{
}
...
...
src/Compilers/CSharp/Portable/Symbols/UnreducedExtensionPropertySymbol.cs
浏览文件 @
a73e0141
...
...
@@ -68,7 +68,15 @@ public UnreducedExtensionPropertySymbol(PropertySymbol unreducedFrom)
public
override
ImmutableArray
<
CustomModifier
>
TypeCustomModifiers
=>
_unreducedFrom
.
TypeCustomModifiers
;
internal
override
Cci
.
CallingConvention
CallingConvention
=>
_unreducedFrom
.
CallingConvention
;
internal
override
Cci
.
CallingConvention
CallingConvention
{
get
{
var
originalCallingConvention
=
_unreducedFrom
.
CallingConvention
;
Debug
.
Assert
((
originalCallingConvention
&
Cci
.
CallingConvention
.
HasThis
)
!=
0
);
return
originalCallingConvention
&
~
Cci
.
CallingConvention
.
HasThis
;
}
}
internal
override
bool
HasSpecialName
=>
_unreducedFrom
.
HasSpecialName
;
...
...
src/Compilers/CSharp/Test/Semantic/Semantics/ExtensionEverythingTests.cs
浏览文件 @
a73e0141
...
...
@@ -449,6 +449,91 @@ static void Main()
parseOptions
:
parseOptions
);
}
[
Fact
]
public
void
BuiltinExtensions
()
{
var
text
=
@"
using System;
extension class MathExt : double
{
public double Cos => Math.Cos(this);
}
extension class IntMathExt : int
{
public double Abs => Math.Abs(this);
}
struct Derp
{
public void Foo()
{
}
}
static class Program
{
static void Main()
{
new Derp().Foo();
var x = 2.0.Cos;
// round it a bit so we don't have to deal with precision.
// x should be somewhere around -0.41614683654
Console.Write((int)(x * 10000));
Console.Write(' ');
Console.Write(1.Abs);
Console.Write((-1).Abs);
}
}
"
;
CompileAndVerify
(
source
:
text
,
additionalRefs
:
additionalRefs
.
Concat
(
new
[]
{
MscorlibRef_v46
}),
expectedOutput
:
"-4161 11"
,
parseOptions
:
parseOptions
);
}
[
Fact
]
public
void
CountProperty
()
{
var
text
=
@"
using System;
using System.Linq;
using System.Collections.Generic;
extension class EnumExt : IEnumerable<int>
{
public int Size => this.Count();
}
extension class StrExt : string
{
public string JoinStr<T>(List<T> stuff)
{
return string.Join(this, stuff);
}
}
static class Program
{
static void Main()
{
Console.Write(new[]{1,2}.Size);
Func<List<string>, string> joinn = "", "".JoinStr;
Console.Write(joinn(new List<string> { ""hello"", ""world"" }));
}
}
"
;
CompileAndVerify
(
source
:
text
,
additionalRefs
:
additionalRefs
.
Concat
(
new
[]
{
MscorlibRef_v46
}),
expectedOutput
:
"2hello, world"
,
parseOptions
:
parseOptions
);
}
[
Fact
]
public
void
DuckDiscovery
()
{
...
...
src/Workspaces/CoreTest/SymbolKeyTests.cs
浏览文件 @
a73e0141
...
...
@@ -306,7 +306,7 @@ public class C
TestRoundTrip
(
symbols
,
compilation
);
}
[
Fact
(
Skip
=
"PROTOTYPE: Extension Everything breaks this, due to reduced method symbols having a receiver type dependent on type parameters"
)
]
[
Fact
]
public
void
TestExtensionMethodReferences
()
{
var
source
=
@"
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录