Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
lwm1986
roslyn
提交
3361cb03
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,发现更多精彩内容 >>
提交
3361cb03
编写于
5月 17, 2017
作者:
G
Gen Lu
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Address review comments
上级
648070f6
变更
5
隐藏空白更改
内联
并排
Showing
5 changed file
with
326 addition
and
82 deletion
+326
-82
src/Compilers/CSharp/Portable/BoundTree/Expression.cs
src/Compilers/CSharp/Portable/BoundTree/Expression.cs
+4
-1
src/Compilers/CSharp/Portable/Lowering/LocalRewriter/LocalRewriter_Call.cs
...arp/Portable/Lowering/LocalRewriter/LocalRewriter_Call.cs
+31
-28
src/Compilers/CSharp/Portable/Lowering/LocalRewriter/LocalRewriter_Conversion.cs
...rtable/Lowering/LocalRewriter/LocalRewriter_Conversion.cs
+1
-1
src/Compilers/CSharp/Test/Semantic/IOperation/IOperationTests_IArgument.cs
...arp/Test/Semantic/IOperation/IOperationTests_IArgument.cs
+252
-41
src/Compilers/Test/Utilities/CSharp/SemanticModelTestBase.cs
src/Compilers/Test/Utilities/CSharp/SemanticModelTestBase.cs
+38
-11
未找到文件。
src/Compilers/CSharp/Portable/BoundTree/Expression.cs
浏览文件 @
3361cb03
...
...
@@ -215,7 +215,10 @@ ImmutableArray<IArgument> IHasArgumentsExpression.ArgumentsInEvaluationOrder
{
get
{
MethodSymbol
accessor
=
this
.
IsLeftOfAssignment
?
this
.
Indexer
.
SetMethod
:
this
.
Indexer
.
GetMethod
;
MethodSymbol
accessor
=
this
.
IsLeftOfAssignment
&&
!
this
.
Indexer
.
ReturnsByRef
?
this
.
Indexer
.
GetOwnOrInheritedSetMethod
()
:
this
.
Indexer
.
GetOwnOrInheritedGetMethod
();
return
BoundCall
.
DeriveArguments
(
this
,
this
.
BinderOpt
,
this
.
Indexer
,
...
...
src/Compilers/CSharp/Portable/Lowering/LocalRewriter/LocalRewriter_Call.cs
浏览文件 @
3361cb03
...
...
@@ -543,7 +543,8 @@ private static bool IsSafeForReordering(BoundExpression expression, RefKind kind
argumentsInEvaluationBuilder
,
missingParametersBuilder
);
AppendMissingOptionalArguments
(
syntax
,
optionalParametersMethod
,
expanded
,
binder
,
missingParametersBuilder
.
ToImmutableAndFree
(),
argumentsInEvaluationBuilder
);
AppendMissingOptionalArguments
(
syntax
,
methodOrIndexer
,
optionalParametersMethod
,
expanded
,
binder
,
missingParametersBuilder
,
argumentsInEvaluationBuilder
);
missingParametersBuilder
.
Free
();
return
argumentsInEvaluationBuilder
.
ToImmutableAndFree
();
}
...
...
@@ -681,7 +682,7 @@ private static ImmutableArray<RefKind> GetRefKindsOrNull(ArrayBuilder<RefKind> r
/* out */
ArrayBuilder
<
ParameterSymbol
>
missingParametersBuilder
)
{
ImmutableArray
<
ParameterSymbol
>
parameters
=
methodOrIndexer
.
GetParameters
();
ArrayBuilder
<
int
>
processedParameters
=
ArrayBuilder
<
int
>.
GetInstance
(
parameters
.
Length
);
PooledHashSet
<
int
>
processedParameters
=
PooledHashSet
<
int
>.
GetInstance
(
);
for
(
int
a
=
0
;
a
<
arguments
.
Length
;
++
a
)
{
...
...
@@ -986,13 +987,15 @@ private static BoundExpression MakeLiteral(SyntaxNode syntax, ConstantValue cons
}
}
private
static
void
AppendMissingOptionalArguments
(
SyntaxNode
syntax
,
private
static
void
AppendMissingOptionalArguments
(
SyntaxNode
syntax
,
Symbol
methodOrIndexer
,
MethodSymbol
optionalParametersMethod
,
bool
expanded
,
Binder
binder
,
ImmutableArray
<
ParameterSymbol
>
missingParameters
,
ArrayBuilder
<
ParameterSymbol
>
missingParameters
,
ArrayBuilder
<
IArgument
>
argumentsBuilder
)
{
ImmutableArray
<
ParameterSymbol
>
parameters
=
methodOrIndexer
.
GetParameters
();
ImmutableArray
<
ParameterSymbol
>
parametersOfOptionalParametersMethod
=
optionalParametersMethod
.
Parameters
;
foreach
(
ParameterSymbol
parameter
in
missingParameters
)
...
...
@@ -1001,11 +1004,11 @@ private static BoundExpression MakeLiteral(SyntaxNode syntax, ConstantValue cons
ArgumentKind
kind
;
// In case of indexer access, missing parameters are corresponding to the indexer symbol, we need to
// get default values base on actual accessor method parameter symbols (but still want to tie resulted IArgument
// get default values base
d
on actual accessor method parameter symbols (but still want to tie resulted IArgument
// to the indexer parameter.)
ParameterSymbol
parameterOfOptionalParametersMethod
=
parametersOfOptionalParametersMethod
[
parameter
.
Ordinal
];
if
(
expanded
&&
parameterOfOptionalParametersMethod
.
Ordinal
==
parameters
OfOptionalParametersMethod
.
Length
-
1
)
if
(
expanded
&&
parameterOfOptionalParametersMethod
.
Ordinal
==
parameters
.
Length
-
1
)
{
Debug
.
Assert
(
parameterOfOptionalParametersMethod
.
IsParams
);
...
...
@@ -1157,9 +1160,7 @@ private BoundExpression GetDefaultParameterValue(SyntaxNode syntax, ParameterSym
if
(
parameterType
.
IsNullableType
())
{
TypeSymbol
nullableType
=
parameterType
.
GetNullableUnderlyingType
();
defaultValue
=
isLowering
?
localRewriter
.
MakeConversionNode
(
lineLiteral
,
nullableType
,
false
)
:
MakeConversionForIOperation
(
lineLiteral
,
nullableType
,
syntax
,
compilation
,
diagnostics
,
false
);
defaultValue
=
MakeConversionNode
(
lineLiteral
,
nullableType
,
@checked
:
false
);
// wrap it in a nullable ctor.
defaultValue
=
new
BoundObjectCreationExpression
(
...
...
@@ -1169,19 +1170,15 @@ private BoundExpression GetDefaultParameterValue(SyntaxNode syntax, ParameterSym
defaultValue
);
}
else
{
defaultValue
=
isLowering
?
localRewriter
.
MakeConversionNode
(
lineLiteral
,
parameterType
,
false
)
:
MakeConversionForIOperation
(
lineLiteral
,
parameterType
,
syntax
,
compilation
,
diagnostics
,
false
);
{
defaultValue
=
MakeConversionNode
(
lineLiteral
,
parameterType
,
@checked
:
false
);
}
}
else
if
(
parameter
.
IsCallerFilePath
&&
((
callerSourceLocation
=
GetCallerLocation
(
syntax
,
enableCallerInfo
))
!=
null
))
{
string
path
=
callerSourceLocation
.
SourceTree
.
GetDisplayPath
(
callerSourceLocation
.
SourceSpan
,
compilation
.
Options
.
SourceReferenceResolver
);
BoundExpression
memberNameLiteral
=
MakeLiteral
(
syntax
,
ConstantValue
.
Create
(
path
),
compilation
.
GetSpecialType
(
SpecialType
.
System_String
),
localRewriter
);
defaultValue
=
isLowering
?
localRewriter
.
MakeConversionNode
(
memberNameLiteral
,
parameterType
,
false
)
:
MakeConversionForIOperation
(
memberNameLiteral
,
parameterType
,
syntax
,
compilation
,
diagnostics
,
false
);
BoundExpression
memberNameLiteral
=
MakeLiteral
(
syntax
,
ConstantValue
.
Create
(
path
),
compilation
.
GetSpecialType
(
SpecialType
.
System_String
),
localRewriter
);
defaultValue
=
MakeConversionNode
(
memberNameLiteral
,
parameterType
,
@checked
:
false
);
}
else
if
(
parameter
.
IsCallerMemberName
&&
((
callerSourceLocation
=
GetCallerLocation
(
syntax
,
enableCallerInfo
))
!=
null
))
{
...
...
@@ -1246,10 +1243,8 @@ private BoundExpression GetDefaultParameterValue(SyntaxNode syntax, ParameterSym
memberName
=
binder
.
ContainingMember
().
GetMemberCallerName
();
}
BoundExpression
memberNameLiteral
=
MakeLiteral
(
syntax
,
ConstantValue
.
Create
(
memberName
),
compilation
.
GetSpecialType
(
SpecialType
.
System_String
),
localRewriter
);
defaultValue
=
isLowering
?
localRewriter
.
MakeConversionNode
(
memberNameLiteral
,
parameterType
,
false
)
:
MakeConversionForIOperation
(
memberNameLiteral
,
parameterType
,
syntax
,
compilation
,
diagnostics
,
false
);
BoundExpression
memberNameLiteral
=
MakeLiteral
(
syntax
,
ConstantValue
.
Create
(
memberName
),
compilation
.
GetSpecialType
(
SpecialType
.
System_String
),
localRewriter
);
defaultValue
=
MakeConversionNode
(
memberNameLiteral
,
parameterType
,
@checked
:
false
);
}
else
if
(
defaultConstantValue
==
ConstantValue
.
NotAvailable
)
{
...
...
@@ -1284,9 +1279,7 @@ private BoundExpression GetDefaultParameterValue(SyntaxNode syntax, ParameterSym
// The parameter's underlying type might not match the constant type. For example, we might have
// a default value of 5 (an integer) but a parameter type of decimal?.
defaultValue
=
isLowering
?
localRewriter
.
MakeConversionNode
(
defaultValue
,
parameterType
.
GetNullableUnderlyingType
(),
@checked
:
false
,
acceptFailingConversion
:
true
)
:
MakeConversionForIOperation
(
defaultValue
,
parameterType
.
GetNullableUnderlyingType
(),
syntax
,
compilation
,
diagnostics
,
@checked
:
false
,
acceptFailingConversion
:
true
);
defaultValue
=
MakeConversionNode
(
defaultValue
,
parameterType
.
GetNullableUnderlyingType
(),
@checked
:
false
,
acceptFailingConversion
:
true
);
// Finally, wrap it in a nullable ctor.
defaultValue
=
new
BoundObjectCreationExpression
(
...
...
@@ -1306,13 +1299,23 @@ private BoundExpression GetDefaultParameterValue(SyntaxNode syntax, ParameterSym
TypeSymbol
constantType
=
compilation
.
GetSpecialType
(
defaultConstantValue
.
SpecialType
);
defaultValue
=
MakeLiteral
(
syntax
,
defaultConstantValue
,
constantType
,
localRewriter
);
// The parameter type might not match the constant type.
defaultValue
=
isLowering
?
localRewriter
.
MakeConversionNode
(
defaultValue
,
parameterType
,
@checked
:
false
,
acceptFailingConversion
:
true
)
:
MakeConversionForIOperation
(
defaultValue
,
parameterType
,
syntax
,
compilation
,
diagnostics
,
@checked
:
false
,
acceptFailingConversion
:
true
);
defaultValue
=
MakeConversionNode
(
defaultValue
,
parameterType
,
@checked
:
false
,
acceptFailingConversion
:
true
);
}
return
defaultValue
;
}
BoundExpression
MakeConversionNode
(
BoundExpression
operand
,
TypeSymbol
type
,
bool
@checked
,
bool
acceptFailingConversion
=
false
)
{
if
(
isLowering
)
{
return
localRewriter
.
MakeConversionNode
(
operand
,
type
,
@checked
,
acceptFailingConversion
);
}
else
{
return
MakeConversionForIOperation
(
operand
,
type
,
syntax
,
compilation
,
diagnostics
,
@checked
,
acceptFailingConversion
);
}
}
}
private
BoundExpression
GetDefaultParameterSpecial
(
SyntaxNode
syntax
,
ParameterSymbol
parameter
)
{
...
...
src/Compilers/CSharp/Portable/Lowering/LocalRewriter/LocalRewriter_Conversion.cs
浏览文件 @
3361cb03
...
...
@@ -506,7 +506,7 @@ private BoundExpression MakeConversionNode(BoundExpression rewrittenOperand, Typ
{
Conversion
conversion
=
MakeConversion
(
operand
,
type
,
compilation
,
diagnostics
,
acceptFailingConversion
);
if
(
conversion
.
Kind
==
ConversionKind
.
Identity
)
if
(
conversion
.
Is
Identity
)
{
return
operand
;
}
...
...
src/Compilers/CSharp/Test/Semantic/IOperation/IOperationTests_IArgument.cs
浏览文件 @
3361cb03
// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using
Microsoft.CodeAnalysis.CSharp.Syntax
;
using
Microsoft.CodeAnalysis.Semantics
;
using
Microsoft.CodeAnalysis.Test.Utilities
;
using
Roslyn.Test.Utilities
;
using
Xunit
;
...
...
@@ -1046,7 +1047,7 @@ void M1()
"
;
var
expectedDiagnostics
=
DiagnosticDescription
.
None
;
VerifyOperationTreeAndDiagnosticsForTest
<
ElementAccessExpressionSyntax
>(
source
,
expectedOperationTree
,
expectedDiagnostics
);
VerifyOperationTreeAndDiagnosticsForTest
<
ElementAccessExpressionSyntax
>(
source
,
expectedOperationTree
,
expectedDiagnostics
,
AdditionalOperationTreeVerifier
:
IndexerAccessArgumentVerifier
.
Verify
);
}
[
Fact
]
...
...
@@ -1076,7 +1077,7 @@ void M1()
"
;
var
expectedDiagnostics
=
DiagnosticDescription
.
None
;
VerifyOperationTreeAndDiagnosticsForTest
<
ElementAccessExpressionSyntax
>(
source
,
expectedOperationTree
,
expectedDiagnostics
);
VerifyOperationTreeAndDiagnosticsForTest
<
ElementAccessExpressionSyntax
>(
source
,
expectedOperationTree
,
expectedDiagnostics
,
AdditionalOperationTreeVerifier
:
IndexerAccessArgumentVerifier
.
Verify
);
}
[
Fact
]
...
...
@@ -1109,7 +1110,7 @@ void M1()
var
expectedDiagnostics
=
DiagnosticDescription
.
None
;
VerifyOperationTreeAndDiagnosticsForTest
<
ElementAccessExpressionSyntax
>(
source
,
expectedOperationTree
,
expectedDiagnostics
);
VerifyOperationTreeAndDiagnosticsForTest
<
ElementAccessExpressionSyntax
>(
source
,
expectedOperationTree
,
expectedDiagnostics
,
AdditionalOperationTreeVerifier
:
IndexerAccessArgumentVerifier
.
Verify
);
}
[
Fact
]
...
...
@@ -1141,7 +1142,7 @@ void M1()
Diagnostic
(
ErrorCode
.
ERR_PropertyLacksGet
,
"this[10]"
).
WithArguments
(
"P.this[int]"
).
WithLocation
(
12
,
27
)
};
VerifyOperationTreeAndDiagnosticsForTest
<
ElementAccessExpressionSyntax
>(
source
,
expectedOperationTree
,
expectedDiagnostics
);
VerifyOperationTreeAndDiagnosticsForTest
<
ElementAccessExpressionSyntax
>(
source
,
expectedOperationTree
,
expectedDiagnostics
,
AdditionalOperationTreeVerifier
:
IndexerAccessArgumentVerifier
.
Verify
);
}
[
Fact
]
...
...
@@ -1175,9 +1176,117 @@ void M1()
Diagnostic
(
ErrorCode
.
ERR_AssgReadonlyProp
,
"this[10]"
).
WithArguments
(
"P.this[int]"
).
WithLocation
(
12
,
19
)
};
VerifyOperationTreeAndDiagnosticsForTest
<
ElementAccessExpressionSyntax
>(
source
,
expectedOperationTree
,
expectedDiagnostics
);
VerifyOperationTreeAndDiagnosticsForTest
<
ElementAccessExpressionSyntax
>(
source
,
expectedOperationTree
,
expectedDiagnostics
,
AdditionalOperationTreeVerifier
:
IndexerAccessArgumentVerifier
.
Verify
);
}
[
Fact
]
public
void
OverridingIndexerWithDefaultArgument
()
{
string
source
=
@"
class Base
{
public virtual int this[int x = 0, int y = 1]
{
set { }
get { System.Console.Write(y); return 0; }
}
}
class Derived : Base
{
public override int this[int x = 8, int y = 9]
{
set { }
}
}
internal class P
{
static void Main()
{
var d = new Derived();
var x = /*<bind>*/d[0]/*</bind>*/;
}
}
"
;
string
expectedOperationTree
=
@"
IIndexedPropertyReferenceExpression: System.Int32 Derived.this[[System.Int32 x = 8], [System.Int32 y = 9]] { set; } (OperationKind.IndexedPropertyReferenceExpression, Type: System.Int32) (Syntax: 'd[0]')
Instance Receiver: ILocalReferenceExpression: d (OperationKind.LocalReferenceExpression, Type: Derived) (Syntax: 'd')
Arguments(2): IArgument (ArgumentKind.Explicit, Matching Parameter: x) (OperationKind.Argument) (Syntax: '0')
ILiteralExpression (Text: 0) (OperationKind.LiteralExpression, Type: System.Int32, Constant: 0) (Syntax: '0')
IArgument (ArgumentKind.DefaultValue, Matching Parameter: y) (OperationKind.Argument) (Syntax: 'd[0]')
ILiteralExpression (OperationKind.LiteralExpression, Type: System.Int32, Constant: 1) (Syntax: 'd[0]')
"
;
var
expectedDiagnostics
=
DiagnosticDescription
.
None
;
string
expectedOutput
=
@"1"
;
VerifyOperationTreeAndDiagnosticsForTest
<
ElementAccessExpressionSyntax
>(
source
,
expectedOperationTree
,
expectedDiagnostics
,
AdditionalOperationTreeVerifier
:
IndexerAccessArgumentVerifier
.
Verify
);
CompileAndVerify
(
new
[]
{
source
},
new
[]
{
SystemRef
},
expectedOutput
:
expectedOutput
);
}
[
Fact
]
public
void
OmittedParamArrayArgumentInIndexerAccess
()
{
string
source
=
@"
class P
{
public int this[int x, params int[] y]
{
set { }
get { return 0; }
}
public void M()
{
/*<bind>*/this[0]/*</bind>*/ = 0;
}
}
"
;
string
expectedOperationTree
=
@"
IIndexedPropertyReferenceExpression: System.Int32 P.this[System.Int32 x, params System.Int32[] y] { get; set; } (OperationKind.IndexedPropertyReferenceExpression, Type: System.Int32) (Syntax: 'this[0]')
Instance Receiver: IInstanceReferenceExpression (InstanceReferenceKind.Explicit) (OperationKind.InstanceReferenceExpression, Type: P) (Syntax: 'this')
Arguments(2): IArgument (ArgumentKind.Explicit, Matching Parameter: x) (OperationKind.Argument) (Syntax: '0')
ILiteralExpression (Text: 0) (OperationKind.LiteralExpression, Type: System.Int32, Constant: 0) (Syntax: '0')
IArgument (ArgumentKind.ParamArray, Matching Parameter: y) (OperationKind.Argument) (Syntax: 'this[0]')
IArrayCreationExpression (Element Type: System.Int32) (OperationKind.ArrayCreationExpression, Type: System.Int32[]) (Syntax: 'this[0]')
Dimension Sizes(1): ILiteralExpression (OperationKind.LiteralExpression, Type: System.Int32, Constant: 0) (Syntax: 'this[0]')
Initializer: IArrayInitializer (0 elements) (OperationKind.ArrayInitializer) (Syntax: 'this[0]')
"
;
var
expectedDiagnostics
=
DiagnosticDescription
.
None
;
VerifyOperationTreeAndDiagnosticsForTest
<
ElementAccessExpressionSyntax
>(
source
,
expectedOperationTree
,
expectedDiagnostics
,
AdditionalOperationTreeVerifier
:
IndexerAccessArgumentVerifier
.
Verify
);
}
[
Fact
]
public
void
AssigningToReturnsByRefIndexer
()
{
string
source
=
@"
class P
{
ref int this[int x]
{
get => throw null;
}
public void M()
{
/*<bind>*/this[0]/*</bind>*/ = 0;
}
}
"
;
string
expectedOperationTree
=
@"
IIndexedPropertyReferenceExpression: ref System.Int32 P.this[System.Int32 x] { get; } (OperationKind.IndexedPropertyReferenceExpression, Type: System.Int32, IsInvalid) (Syntax: 'this[0]')
Instance Receiver: IInstanceReferenceExpression (InstanceReferenceKind.Explicit) (OperationKind.InstanceReferenceExpression, Type: P) (Syntax: 'this')
Arguments(1): IArgument (ArgumentKind.Explicit, Matching Parameter: x) (OperationKind.Argument) (Syntax: '0')
ILiteralExpression (Text: 0) (OperationKind.LiteralExpression, Type: System.Int32, Constant: 0) (Syntax: '0')
"
;
var
expectedDiagnostics
=
DiagnosticDescription
.
None
;
VerifyOperationTreeAndDiagnosticsForTest
<
ElementAccessExpressionSyntax
>(
source
,
expectedOperationTree
,
expectedDiagnostics
,
AdditionalOperationTreeVerifier
:
IndexerAccessArgumentVerifier
.
Verify
);
}
[
ClrOnlyFact
(
ClrOnlyReason
.
Ilasm
)]
public
void
AssigningToIndexer_UsingDefaultArgumentFromSetter
()
{
...
...
@@ -1205,15 +1314,25 @@ .maxstack 8
{
.param [1] = int32(0x00000001)
.param [2] = int32(0x00000002)
// Code size
7 (0x7
)
.maxstack
1
// Code size
35 (0x23
)
.maxstack
3
.locals init ([0] int32 V_0)
IL_0000: nop
IL_0001: ldc.i4.0
IL_0002: stloc.0
IL_0003: br.s IL_0005
IL_0005: ldloc.0
IL_0006: ret
IL_0001: ldstr ""{0} {1}""
IL_0006: ldarg.1
IL_0007: box [mscorlib]System.Int32
IL_000c: ldarg.2
IL_000d: box [mscorlib]System.Int32
IL_0012: call string [mscorlib]System.String::Format(string,
object,
object)
IL_0017: call void [mscorlib]System.Console::WriteLine(string)
IL_001c: nop
IL_001d: ldc.i4.0
IL_001e: stloc.0
IL_001f: br.s IL_0021
IL_0021: ldloc.0
IL_0022: ret
} // end of method P::get_Item
.method public hidebysig specialname instance void
...
...
@@ -1223,10 +1342,20 @@ .locals init ([0] int32 V_0)
{
.param [1] = int32(0x00000003)
.param [2] = int32(0x00000004)
// Code size
2 (0x2
)
// Code size
30 (0x1e
)
.maxstack 8
IL_0000: nop
IL_0001: ret
IL_0001: ldstr ""{0} {1}""
IL_0006: ldarg.1
IL_0007: box [mscorlib]System.Int32
IL_000c: ldarg.2
IL_000d: box [mscorlib]System.Int32
IL_0012: call string [mscorlib]System.String::Format(string,
object,
object)
IL_0017: call void [mscorlib]System.Console::WriteLine(string)
IL_001c: nop
IL_001d: ret
} // end of method P::set_Item
...
...
@@ -1245,7 +1374,7 @@ .maxstack 8
var
csharp
=
@"
class C
{
public
void M1(
)
public
static void Main(string[] args
)
{
P p = new P();
/*<bind>*/p[10]/*</bind>*/ = 9;
...
...
@@ -1260,8 +1389,12 @@ public void M1()
IArgument (ArgumentKind.DefaultValue, Matching Parameter: j) (OperationKind.Argument) (Syntax: 'p[10]')
ILiteralExpression (OperationKind.LiteralExpression, Type: System.Int32, Constant: 4) (Syntax: 'p[10]')"
;
var
expectedDiagnostics
=
DiagnosticDescription
.
None
;
var
expectedOutput
=
@"10 4
"
;
VerifyOperationTreeAndDiagnosticsForTestWithIL
<
ElementAccessExpressionSyntax
>(
csharp
,
il
,
expectedOperationTree
,
expectedDiagnostics
);
var
ilReference
=
VerifyOperationTreeAndDiagnosticsForTestWithIL
<
ElementAccessExpressionSyntax
>(
csharp
,
il
,
expectedOperationTree
,
expectedDiagnostics
,
AdditionalOperationTreeVerifier
:
IndexerAccessArgumentVerifier
.
Verify
);
CompileAndVerify
(
new
[]
{
csharp
},
new
[]
{
SystemRef
,
ilReference
},
expectedOutput
:
expectedOutput
);
}
[
ClrOnlyFact
(
ClrOnlyReason
.
Ilasm
)]
...
...
@@ -1291,28 +1424,48 @@ .maxstack 8
{
.param [1] = int32(0x00000001)
.param [2] = int32(0x00000002)
// Code size
7 (0x7
)
.maxstack
1
// Code size
35 (0x23
)
.maxstack
3
.locals init ([0] int32 V_0)
IL_0000: nop
IL_0001: ldc.i4.0
IL_0002: stloc.0
IL_0003: br.s IL_0005
IL_0005: ldloc.0
IL_0006: ret
IL_0001: ldstr ""{0} {1}""
IL_0006: ldarg.1
IL_0007: box [mscorlib]System.Int32
IL_000c: ldarg.2
IL_000d: box [mscorlib]System.Int32
IL_0012: call string [mscorlib]System.String::Format(string,
object,
object)
IL_0017: call void [mscorlib]System.Console::WriteLine(string)
IL_001c: nop
IL_001d: ldc.i4.0
IL_001e: stloc.0
IL_001f: br.s IL_0021
IL_0021: ldloc.0
IL_0022: ret
} // end of method P::get_Item
.method public hidebysig specialname instance void
set_Item([opt] int32 i,
[opt] int32 j,
int32 'value') cil managed
{
{
.param [1] = int32(0x00000003)
.param [2] = int32(0x00000004)
// Code size
2 (0x2
)
// Code size
30 (0x1e
)
.maxstack 8
IL_0000: nop
IL_0001: ret
IL_0001: ldstr ""{0} {1}""
IL_0006: ldarg.1
IL_0007: box [mscorlib]System.Int32
IL_000c: ldarg.2
IL_000d: box [mscorlib]System.Int32
IL_0012: call string [mscorlib]System.String::Format(string,
object,
object)
IL_0017: call void [mscorlib]System.Console::WriteLine(string)
IL_001c: nop
IL_001d: ret
} // end of method P::set_Item
...
...
@@ -1331,7 +1484,7 @@ .maxstack 8
var
csharp
=
@"
class C
{
public
void M1(
)
public
static void Main(string[] args
)
{
P p = new P();
var x = /*<bind>*/p[10]/*</bind>*/;
...
...
@@ -1348,7 +1501,12 @@ public void M1()
"
;
var
expectedDiagnostics
=
DiagnosticDescription
.
None
;
VerifyOperationTreeAndDiagnosticsForTestWithIL
<
ElementAccessExpressionSyntax
>(
csharp
,
il
,
expectedOperationTree
,
expectedDiagnostics
);
var
expectedOutput
=
@"10 2
"
;
var
ilReference
=
VerifyOperationTreeAndDiagnosticsForTestWithIL
<
ElementAccessExpressionSyntax
>(
csharp
,
il
,
expectedOperationTree
,
expectedDiagnostics
,
AdditionalOperationTreeVerifier
:
IndexerAccessArgumentVerifier
.
Verify
);
CompileAndVerify
(
new
[]
{
csharp
},
new
[]
{
SystemRef
,
ilReference
},
expectedOutput
:
expectedOutput
);
}
[
ClrOnlyFact
(
ClrOnlyReason
.
Ilasm
)]
...
...
@@ -1378,28 +1536,48 @@ .maxstack 8
{
.param [1] = int32(0x00000001)
.param [2] = int32(0x00000002)
// Code size
7 (0x7
)
.maxstack
1
// Code size
35 (0x23
)
.maxstack
3
.locals init ([0] int32 V_0)
IL_0000: nop
IL_0001: ldc.i4.0
IL_0002: stloc.0
IL_0003: br.s IL_0005
IL_0005: ldloc.0
IL_0006: ret
IL_0001: ldstr ""{0} {1}""
IL_0006: ldarg.1
IL_0007: box [mscorlib]System.Int32
IL_000c: ldarg.2
IL_000d: box [mscorlib]System.Int32
IL_0012: call string [mscorlib]System.String::Format(string,
object,
object)
IL_0017: call void [mscorlib]System.Console::WriteLine(string)
IL_001c: nop
IL_001d: ldc.i4.0
IL_001e: stloc.0
IL_001f: br.s IL_0021
IL_0021: ldloc.0
IL_0022: ret
} // end of method P::get_Item
.method public hidebysig specialname instance void
set_Item([opt] int32 i,
[opt] int32 j,
int32 'value') cil managed
{
{
.param [1] = int32(0x00000003)
.param [2] = int32(0x00000004)
// Code size
2 (0x2
)
// Code size
30 (0x1e
)
.maxstack 8
IL_0000: nop
IL_0001: ret
IL_0001: ldstr ""{0} {1}""
IL_0006: ldarg.1
IL_0007: box [mscorlib]System.Int32
IL_000c: ldarg.2
IL_000d: box [mscorlib]System.Int32
IL_0012: call string [mscorlib]System.String::Format(string,
object,
object)
IL_0017: call void [mscorlib]System.Console::WriteLine(string)
IL_001c: nop
IL_001d: ret
} // end of method P::set_Item
...
...
@@ -1418,7 +1596,7 @@ .maxstack 8
var
csharp
=
@"
class C
{
public
void M1(
)
public
static void Main(string[] args
)
{
P p = new P();
/*<bind>*/p[10]/*</bind>*/ += 99;
...
...
@@ -1434,7 +1612,13 @@ public void M1()
ILiteralExpression (OperationKind.LiteralExpression, Type: System.Int32, Constant: 2) (Syntax: 'p[10]')"
;
var
expectedDiagnostics
=
DiagnosticDescription
.
None
;
VerifyOperationTreeAndDiagnosticsForTestWithIL
<
ElementAccessExpressionSyntax
>(
csharp
,
il
,
expectedOperationTree
,
expectedDiagnostics
);
var
expectedOutput
=
@"10 2
10 2
"
;
var
ilReference
=
VerifyOperationTreeAndDiagnosticsForTestWithIL
<
ElementAccessExpressionSyntax
>(
csharp
,
il
,
expectedOperationTree
,
expectedDiagnostics
,
AdditionalOperationTreeVerifier
:
IndexerAccessArgumentVerifier
.
Verify
);
CompileAndVerify
(
new
[]
{
csharp
},
new
[]
{
SystemRef
,
ilReference
},
expectedOutput
:
expectedOutput
);
}
[
ClrOnlyFact
(
ClrOnlyReason
.
Ilasm
)]
...
...
@@ -1487,5 +1671,32 @@ public void M2()
VerifyOperationTreeAndDiagnosticsForTestWithIL
<
InvocationExpressionSyntax
>(
csharp
,
il
,
expectedOperationTree
,
expectedDiagnostics
);
}
}
private
class
IndexerAccessArgumentVerifier
:
OperationWalker
{
public
static
void
Verify
(
IOperation
operation
)
{
var
walker
=
new
IndexerAccessArgumentVerifier
();
walker
.
Visit
(
operation
);
}
public
override
void
VisitIndexedPropertyReferenceExpression
(
IIndexedPropertyReferenceExpression
operation
)
{
if
(
operation
.
IsInvalid
)
{
return
;
}
// Check if the parameter symbol for argument is corresponding to indexer instead of accessor.
var
indexerSymbol
=
operation
.
Property
;
foreach
(
var
argument
in
operation
.
ArgumentsInEvaluationOrder
)
{
if
(!
argument
.
IsInvalid
)
{
Assert
.
True
(
argument
.
Parameter
.
ContainingSymbol
==
indexerSymbol
);
}
}
}
}
}
}
\ No newline at end of file
src/Compilers/Test/Utilities/CSharp/SemanticModelTestBase.cs
浏览文件 @
3361cb03
...
...
@@ -221,8 +221,8 @@ protected CompilationUtils.SemanticInfoSummary GetSemanticInfoForTest(string tes
return
GetSemanticInfoForTest
<
ExpressionSyntax
>(
testSrc
);
}
protected
string
GetOperationTree
ForTest
<
TSyntaxNode
>(
CSharpCompilation
compilation
)
where
TSyntaxNode
:
SyntaxNode
protected
IOperation
GetOperation
ForTest
<
TSyntaxNode
>(
CSharpCompilation
compilation
)
where
TSyntaxNode
:
SyntaxNode
{
var
tree
=
compilation
.
SyntaxTrees
[
0
];
var
model
=
compilation
.
GetSemanticModel
(
tree
);
...
...
@@ -232,7 +232,18 @@ protected string GetOperationTreeForTest<TSyntaxNode>(CSharpCompilation compilat
return
null
;
}
var
operation
=
model
.
GetOperationInternal
(
syntaxNode
);
return
model
.
GetOperationInternal
(
syntaxNode
);
}
protected
string
GetOperationTreeForTest
<
TSyntaxNode
>(
CSharpCompilation
compilation
)
where
TSyntaxNode
:
SyntaxNode
{
var
operation
=
GetOperationForTest
<
TSyntaxNode
>(
compilation
);
return
operation
!=
null
?
OperationTreeVerifier
.
GetOperationTree
(
operation
)
:
null
;
}
protected
string
GetOperationTreeForTest
(
IOperation
operation
)
{
return
operation
!=
null
?
OperationTreeVerifier
.
GetOperationTree
(
operation
)
:
null
;
}
...
...
@@ -243,11 +254,13 @@ protected string GetOperationTreeForTest<TSyntaxNode>(string testSrc, string exp
return
GetOperationTreeForTest
<
TSyntaxNode
>(
compilation
);
}
protected
void
VerifyOperationTreeForTest
<
TSyntaxNode
>(
CSharpCompilation
compilation
,
string
expectedOperationTree
)
protected
void
VerifyOperationTreeForTest
<
TSyntaxNode
>(
CSharpCompilation
compilation
,
string
expectedOperationTree
,
Action
<
IOperation
>
AdditionalOperationTreeVerifier
=
null
)
where
TSyntaxNode
:
SyntaxNode
{
var
actualOperationTree
=
GetOperationTreeForTest
<
TSyntaxNode
>(
compilation
);
var
actualOperation
=
GetOperationForTest
<
TSyntaxNode
>(
compilation
);
var
actualOperationTree
=
GetOperationTreeForTest
(
actualOperation
);
OperationTreeVerifier
.
Verify
(
expectedOperationTree
,
actualOperationTree
);
AdditionalOperationTreeVerifier
?.
Invoke
(
actualOperation
);
}
protected
void
VerifyOperationTreeForTest
<
TSyntaxNode
>(
string
testSrc
,
string
expectedOperationTree
,
CSharpCompilationOptions
compilationOptions
=
null
,
CSharpParseOptions
parseOptions
=
null
)
...
...
@@ -257,29 +270,43 @@ protected void VerifyOperationTreeForTest<TSyntaxNode>(string testSrc, string ex
OperationTreeVerifier
.
Verify
(
expectedOperationTree
,
actualOperationTree
);
}
protected
void
VerifyOperationTreeAndDiagnosticsForTest
<
TSyntaxNode
>(
CSharpCompilation
compilation
,
string
expectedOperationTree
,
DiagnosticDescription
[]
expectedDiagnostics
)
protected
void
VerifyOperationTreeAndDiagnosticsForTest
<
TSyntaxNode
>(
CSharpCompilation
compilation
,
string
expectedOperationTree
,
DiagnosticDescription
[]
expectedDiagnostics
,
Action
<
IOperation
>
AdditionalOperationTreeVerifier
=
null
)
where
TSyntaxNode
:
SyntaxNode
{
var
actualDiagnostics
=
compilation
.
GetDiagnostics
().
Where
(
d
=>
d
.
Severity
!=
DiagnosticSeverity
.
Hidden
);
actualDiagnostics
.
Verify
(
expectedDiagnostics
);
VerifyOperationTreeForTest
<
TSyntaxNode
>(
compilation
,
expectedOperationTree
);
VerifyOperationTreeForTest
<
TSyntaxNode
>(
compilation
,
expectedOperationTree
,
AdditionalOperationTreeVerifier
);
}
private
static
readonly
MetadataReference
[]
s_defaultOperationReferences
=
new
[]
{
SystemRef
,
SystemCoreRef
,
ValueTupleRef
,
SystemRuntimeFacadeRef
};
protected
void
VerifyOperationTreeAndDiagnosticsForTest
<
TSyntaxNode
>(
string
testSrc
,
string
expectedOperationTree
,
DiagnosticDescription
[]
expectedDiagnostics
,
CSharpCompilationOptions
compilationOptions
=
null
,
CSharpParseOptions
parseOptions
=
null
,
MetadataReference
[]
additionalReferences
=
null
)
protected
void
VerifyOperationTreeAndDiagnosticsForTest
<
TSyntaxNode
>(
string
testSrc
,
string
expectedOperationTree
,
DiagnosticDescription
[]
expectedDiagnostics
,
CSharpCompilationOptions
compilationOptions
=
null
,
CSharpParseOptions
parseOptions
=
null
,
MetadataReference
[]
additionalReferences
=
null
,
Action
<
IOperation
>
AdditionalOperationTreeVerifier
=
null
)
where
TSyntaxNode
:
SyntaxNode
{
var
references
=
additionalReferences
==
null
?
s_defaultOperationReferences
:
additionalReferences
.
Concat
(
s_defaultOperationReferences
);
var
compilation
=
CreateStandardCompilation
(
testSrc
,
references
,
sourceFileName
:
"file.cs"
,
options
:
compilationOptions
??
TestOptions
.
ReleaseDll
,
parseOptions
:
parseOptions
);
VerifyOperationTreeAndDiagnosticsForTest
<
TSyntaxNode
>(
compilation
,
expectedOperationTree
,
expectedDiagnostics
);
VerifyOperationTreeAndDiagnosticsForTest
<
TSyntaxNode
>(
compilation
,
expectedOperationTree
,
expectedDiagnostics
,
AdditionalOperationTreeVerifier
);
}
protected
void
VerifyOperationTreeAndDiagnosticsForTestWithIL
<
TSyntaxNode
>(
string
testSrc
,
string
ilSource
,
string
expectedOperationTree
,
DiagnosticDescription
[]
expectedDiagnostics
,
CSharpCompilationOptions
compilationOptions
=
null
,
CSharpParseOptions
parseOptions
=
null
,
MetadataReference
[]
additionalReferences
=
null
)
protected
MetadataReference
VerifyOperationTreeAndDiagnosticsForTestWithIL
<
TSyntaxNode
>(
string
testSrc
,
string
ilSource
,
string
expectedOperationTree
,
DiagnosticDescription
[]
expectedDiagnostics
,
CSharpCompilationOptions
compilationOptions
=
null
,
CSharpParseOptions
parseOptions
=
null
,
MetadataReference
[]
additionalReferences
=
null
,
Action
<
IOperation
>
AdditionalOperationTreeVerifier
=
null
)
where
TSyntaxNode
:
SyntaxNode
{
var
ilReference
=
CreateMetadataReferenceFromIlSource
(
ilSource
);
VerifyOperationTreeAndDiagnosticsForTest
<
TSyntaxNode
>(
testSrc
,
expectedOperationTree
,
expectedDiagnostics
,
compilationOptions
,
parseOptions
,
new
[]
{
ilReference
});
VerifyOperationTreeAndDiagnosticsForTest
<
TSyntaxNode
>(
testSrc
,
expectedOperationTree
,
expectedDiagnostics
,
compilationOptions
,
parseOptions
,
new
[]
{
ilReference
},
AdditionalOperationTreeVerifier
);
return
ilReference
;
}
}
}
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录