Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
dotNET
Roslyn
提交
79b2bc6e
R
Roslyn
项目概览
dotNET
/
Roslyn
通知
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,发现更多精彩内容 >>
提交
79b2bc6e
编写于
5月 08, 2017
作者:
J
Julien Couvreur
提交者:
GitHub
5月 08, 2017
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Fix crash with typeless tuple in "as" operator (#18416)
上级
956b17ef
变更
8
隐藏空白更改
内联
并排
Showing
8 changed file
with
602 addition
and
13 deletion
+602
-13
src/Compilers/CSharp/Portable/Binder/Binder_Conversions.cs
src/Compilers/CSharp/Portable/Binder/Binder_Conversions.cs
+3
-3
src/Compilers/CSharp/Portable/Binder/Binder_Operators.cs
src/Compilers/CSharp/Portable/Binder/Binder_Operators.cs
+8
-6
src/Compilers/CSharp/Portable/CSharpResources.Designer.cs
src/Compilers/CSharp/Portable/CSharpResources.Designer.cs
+9
-0
src/Compilers/CSharp/Portable/CSharpResources.resx
src/Compilers/CSharp/Portable/CSharpResources.resx
+3
-0
src/Compilers/CSharp/Portable/Errors/ErrorCode.cs
src/Compilers/CSharp/Portable/Errors/ErrorCode.cs
+1
-0
src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenTupleTest.cs
src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenTupleTest.cs
+196
-4
src/Compilers/VisualBasic/Test/Emit/CodeGen/CodeGenTuples.vb
src/Compilers/VisualBasic/Test/Emit/CodeGen/CodeGenTuples.vb
+359
-0
src/EditorFeatures/VisualBasicTest/CodeActions/InlineTemporary/InlineTemporaryTests.vb
...cTest/CodeActions/InlineTemporary/InlineTemporaryTests.vb
+23
-0
未找到文件。
src/Compilers/CSharp/Portable/Binder/Binder_Conversions.cs
浏览文件 @
79b2bc6e
...
...
@@ -94,7 +94,7 @@ internal partial class Binder
}
if
(
conversion
.
IsTupleLiteralConversion
||
(
conversion
.
Kind
==
ConversionKind
.
Implicit
Nullable
&&
conversion
.
UnderlyingConversions
[
0
].
IsTupleLiteralConversion
))
(
conversion
.
Is
Nullable
&&
conversion
.
UnderlyingConversions
[
0
].
IsTupleLiteralConversion
))
{
return
CreateTupleLiteralConversion
(
syntax
,
(
BoundTupleLiteral
)
source
,
conversion
,
isCast
,
destination
,
diagnostics
);
}
...
...
@@ -343,12 +343,12 @@ private BoundExpression CreateTupleLiteralConversion(SyntaxNode syntax, BoundTup
{
// We have a successful tuple conversion; rather than producing a separate conversion node
// which is a conversion on top of a tuple literal, tuple conversion is an element-wise conversion of arguments.
Debug
.
Assert
(
(
conversion
.
Kind
==
ConversionKind
.
ImplicitNullable
)
==
destination
.
IsNullableType
());
Debug
.
Assert
(
conversion
.
IsNullable
==
destination
.
IsNullableType
());
var
destinationWithoutNullable
=
destination
;
var
conversionWithoutNullable
=
conversion
;
if
(
conversion
.
Kind
==
ConversionKind
.
Implicit
Nullable
)
if
(
conversion
.
Is
Nullable
)
{
destinationWithoutNullable
=
destination
.
GetNullableUnderlyingType
();
conversionWithoutNullable
=
conversion
.
UnderlyingConversions
[
0
];
...
...
src/Compilers/CSharp/Portable/Binder/Binder_Operators.cs
浏览文件 @
79b2bc6e
...
...
@@ -3009,6 +3009,14 @@ private BoundExpression BindAsOperator(BinaryExpressionSyntax node, DiagnosticBa
}
return
new
BoundAsOperator
(
node
,
operand
,
typeExpression
,
Conversion
.
NoConversion
,
resultType
,
hasErrors
:
true
);
case
BoundKind
.
TupleLiteral
:
if
((
object
)
operand
.
Type
==
null
)
{
Error
(
diagnostics
,
ErrorCode
.
ERR_TypelessTupleInAs
,
node
);
return
new
BoundAsOperator
(
node
,
operand
,
typeExpression
,
Conversion
.
NoConversion
,
resultType
,
hasErrors
:
true
);
}
break
;
}
if
(
operand
.
HasAnyErrors
||
targetTypeKind
==
TypeKind
.
Error
)
...
...
@@ -3073,12 +3081,6 @@ private BoundExpression BindAsOperator(BinaryExpressionSyntax node, DiagnosticBa
type
:
GetSpecialType
(
SpecialType
.
System_Object
,
diagnostics
,
node
));
}
if
(
operand
.
Kind
==
BoundKind
.
MethodGroup
)
{
Error
(
diagnostics
,
ErrorCode
.
ERR_NoExplicitBuiltinConv
,
node
,
MessageID
.
IDS_MethodGroup
.
Localize
(),
targetType
);
return
new
BoundAsOperator
(
node
,
operand
,
typeExpression
,
Conversion
.
NoConversion
,
resultType
,
hasErrors
:
true
);
}
var
operandType
=
operand
.
Type
;
Debug
.
Assert
((
object
)
operandType
!=
null
);
var
operandTypeKind
=
operandType
.
TypeKind
;
...
...
src/Compilers/CSharp/Portable/CSharpResources.Designer.cs
浏览文件 @
79b2bc6e
...
...
@@ -9151,6 +9151,15 @@ internal class CSharpResources {
}
}
/// <summary>
/// Looks up a localized string similar to The first operand of an 'as' operator may not be a tuple literal without a natural type..
/// </summary>
internal static string ERR_TypelessTupleInAs {
get {
return ResourceManager.GetString("ERR_TypelessTupleInAs", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Type parameter declaration must be an identifier not a type.
/// </summary>
...
...
src/Compilers/CSharp/Portable/CSharpResources.resx
浏览文件 @
79b2bc6e
...
...
@@ -2165,6 +2165,9 @@ If such a class is used as a base class and if the deriving class defines a dest
<data
name=
"ERR_LambdaInIsAs"
xml:space=
"preserve"
>
<value>
The first operand of an 'is' or 'as' operator may not be a lambda expression, anonymous method, or method group.
</value>
</data>
<data
name=
"ERR_TypelessTupleInAs"
xml:space=
"preserve"
>
<value>
The first operand of an 'as' operator may not be a tuple literal without a natural type.
</value>
</data>
<data
name=
"ERR_ExpressionTreeContainsMultiDimensionalArrayInitializer"
xml:space=
"preserve"
>
<value>
An expression tree may not contain a multidimensional array initializer
</value>
</data>
...
...
src/Compilers/CSharp/Portable/Errors/ErrorCode.cs
浏览文件 @
79b2bc6e
...
...
@@ -1475,6 +1475,7 @@ internal enum ErrorCode
ERR_CompilerAndLanguageVersion
=
8304
,
WRN_Experimental
=
8305
,
ERR_TupleInferredNamesNotAvailable
=
8306
,
ERR_TypelessTupleInAs
=
8307
,
#
region
diagnostics
for
C
#
7.1
...
...
src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenTupleTest.cs
浏览文件 @
79b2bc6e
...
...
@@ -6605,6 +6605,176 @@ static void Main()
);
}
[Fact]
public void TupleExplicitNullableConversionWithTypelessTuple()
{
var source = @"
class C
{
static void Main()
{
var x = ((int, string)?) (1, null);
System.Console.Write(x);
}
}
";
var comp = CreateStandardCompilation(source, references: new[] { ValueTupleRef, SystemRuntimeFacadeRef }, options: TestOptions.DebugExe);
comp.VerifyEmitDiagnostics();
CompileAndVerify(comp, expectedOutput: "(1, )");
var tree = comp.SyntaxTrees.Single();
var model = comp.GetSemanticModel(tree);
var declaration = tree.GetRoot().DescendantNodes().OfType<LocalDeclarationStatementSyntax>().First();
var value = declaration.Declaration.Variables.First().Initializer.Value;
Assert.Equal("((int, string)?) (1, null)", value.ToString());
var castConversion = model.GetConversion(value);
Assert.Equal(ConversionKind.Identity, castConversion.Kind);
var tuple = ((CastExpressionSyntax)value).Expression;
Assert.Equal("(1, null)", tuple.ToString());
var tupleConversion = model.GetConversion(tuple);
Assert.Equal(ConversionKind.ExplicitNullable, tupleConversion.Kind);
Assert.Equal(1, tupleConversion.UnderlyingConversions.Length);
Assert.Equal(ConversionKind.ExplicitTupleLiteral, tupleConversion.UnderlyingConversions[0].Kind);
}
[Fact]
public void TupleImplicitNullableConversionWithTypelessTuple()
{
var source = @"
class C
{
static void Main()
{
(int, string)? x = (1, null);
System.Console.Write(x);
}
}
";
var comp = CreateStandardCompilation(source, references: new[] { ValueTupleRef, SystemRuntimeFacadeRef }, options: TestOptions.DebugExe);
comp.VerifyEmitDiagnostics();
CompileAndVerify(comp, expectedOutput: "(1, )");
var tree = comp.SyntaxTrees.Single();
var model = comp.GetSemanticModel(tree);
var declaration = tree.GetRoot().DescendantNodes().OfType<LocalDeclarationStatementSyntax>().First();
var value = declaration.Declaration.Variables.First().Initializer.Value;
Assert.Equal("(1, null)", value.ToString());
var tupleConversion = model.GetConversion(value);
Assert.Equal(ConversionKind.ImplicitNullable, tupleConversion.Kind);
Assert.Equal(1, tupleConversion.UnderlyingConversions.Length);
Assert.Equal(ConversionKind.ImplicitTupleLiteral, tupleConversion.UnderlyingConversions[0].Kind);
}
[Fact]
public void TupleImplicitNullableAndCustomConversionsWithTypelessTuple()
{
var source = @"
struct C
{
static void Main()
{
C? x = (1, null);
System.Console.Write(x);
var x2 = (C)(2, null);
System.Console.Write(x2);
var x3 = (C?)(3, null);
System.Console.Write(x3);
}
public static implicit operator C((int, string) x)
{
return new C();
}
}
";
var comp = CreateStandardCompilation(source, references: new[] { ValueTupleRef, SystemRuntimeFacadeRef }, options: TestOptions.DebugExe);
comp.VerifyEmitDiagnostics();
CompileAndVerify(comp, expectedOutput: "CCC");
var tree = comp.SyntaxTrees.Single();
var model = comp.GetSemanticModel(tree);
var tuples = tree.GetRoot().DescendantNodes().OfType<TupleExpressionSyntax>();
var tuple1 = tuples.ElementAt(0);
Assert.Equal("(1, null)", tuple1.ToString());
Assert.Null(model.GetTypeInfo(tuple1).Type);
Assert.Equal("C?", model.GetTypeInfo(tuple1).ConvertedType.ToTestDisplayString());
var conversion1 = model.GetConversion(tuple1);
Assert.Equal(ConversionKind.ImplicitUserDefined, conversion1.Kind);
Assert.True(conversion1.UnderlyingConversions.IsDefault);
var tuple2 = tuples.ElementAt(1);
Assert.Equal("(2, null)", tuple2.ToString());
Assert.Null(model.GetTypeInfo(tuple2).Type);
Assert.Equal("(System.Int32, System.String)", model.GetTypeInfo(tuple2).ConvertedType.ToTestDisplayString());
var conversion2 = model.GetConversion(tuple2);
Assert.Equal(ConversionKind.ImplicitTupleLiteral, conversion2.Kind);
Assert.False(conversion2.UnderlyingConversions.IsDefault);
var tuple3 = tuples.ElementAt(2);
Assert.Equal("(3, null)", tuple3.ToString());
Assert.Null(model.GetTypeInfo(tuple3).Type);
Assert.Equal("(System.Int32, System.String)", model.GetTypeInfo(tuple3).ConvertedType.ToTestDisplayString());
var conversion3 = model.GetConversion(tuple3);
Assert.Equal(ConversionKind.ImplicitTupleLiteral, conversion3.Kind);
Assert.False(conversion3.UnderlyingConversions.IsDefault);
}
[Fact]
public void TupleImplicitNullableAndCustomConversionsWithTypelessTupleInAsOperator()
{
var source = @"
struct C
{
static void Main()
{
var x4 = (1, null) as C;
System.Console.Write(x4);
var x5 = (2, null) as C?;
System.Console.Write(x5);
}
public static implicit operator C((int, string) x)
{
return new C();
}
}
";
var comp = CreateStandardCompilation(source, references: new[] { ValueTupleRef, SystemRuntimeFacadeRef }, options: TestOptions.DebugExe);
comp.VerifyEmitDiagnostics(
// (6,18): error CS8305: The first operand of an 'as' operator may not be a tuple literal without a natural type.
// var x4 = (1, null) as C;
Diagnostic(ErrorCode.ERR_TypelessTupleInAs, "(1, null) as C").WithLocation(6, 18),
// (8,18): error CS8305: The first operand of an 'as' operator may not be a tuple literal without a natural type.
// var x5 = (2, null) as C?;
Diagnostic(ErrorCode.ERR_TypelessTupleInAs, "(2, null) as C?").WithLocation(8, 18)
);
var tree = comp.SyntaxTrees.Single();
var model = comp.GetSemanticModel(tree);
var tuples = tree.GetRoot().DescendantNodes().OfType<TupleExpressionSyntax>();
verifyTuple("(1, null)", tuples.ElementAt(0));
verifyTuple("(2, null)", tuples.ElementAt(1));
void verifyTuple(string expected, TupleExpressionSyntax tuple)
{
Assert.Equal(expected, tuple.ToString());
Assert.Null(model.GetTypeInfo(tuple).Type);
Assert.Null(model.GetTypeInfo(tuple).ConvertedType);
var conversion = model.GetConversion(tuple);
Assert.Equal(ConversionKind.Identity, conversion.Kind);
Assert.True(conversion.UnderlyingConversions.IsDefault);
}
}
[Fact]
public void TupleTargetTypeLambda()
{
...
...
@@ -7069,8 +7239,8 @@ static void Main()
Assert.Equal(@"(e: 1, f: ""hello"")", node.ToString());
Assert.Equal("(System.Int32 e, System.String f)", model.GetTypeInfo(node).Type.ToTestDisplayString());
Assert.Equal("(System.Int
32 e, System.String f)
", model.GetTypeInfo(node).ConvertedType.ToTestDisplayString());
Assert.Equal(Conversion
.Identity, model.GetConversion(node)
);
Assert.Equal("(System.Int
16 c, System.String d)?
", model.GetTypeInfo(node).ConvertedType.ToTestDisplayString());
Assert.Equal(Conversion
Kind.ExplicitNullable, model.GetConversion(node).Kind
);
// semantic model returns topmost conversion from the sequence of conversions for
// ((short c, string d)?)(e: 1, f: ""hello"")
...
...
@@ -7295,8 +7465,8 @@ static void Main()
Assert.Equal(@"(e: 1, f: ""hello"")", node.ToString());
Assert.Equal("(System.Int32 e, System.String f)", model.GetTypeInfo(node).Type.ToTestDisplayString());
Assert.Equal("(System.Int32
e, System.String f)
", model.GetTypeInfo(node).ConvertedType.ToTestDisplayString());
Assert.Equal(Conversion
.Identity, model.GetConversion(node)
);
Assert.Equal("(System.Int32
c, System.String d)?
", model.GetTypeInfo(node).ConvertedType.ToTestDisplayString());
Assert.Equal(Conversion
Kind.ExplicitNullable, model.GetConversion(node).Kind
);
// semantic model returns topmost conversion from the sequence of conversions for
// ((int c, string d)?)(e: 1, f: ""hello"")
...
...
@@ -22680,5 +22850,27 @@ public struct ValueTuple<T1, T2>
Assert.False(tuple3.IsErrorType());
Assert.Equal(libWithVTRef.Display, tuple3.ContainingAssembly.MetadataName.ToString());
}
[Fact]
[WorkItem(17962, "https://github.com/dotnet/roslyn/issues/17962")]
public void TupleWithAsOperator()
{
var source = @"
class C
{
void M<T>()
{
var x = (0, null) as (int, T)?;
System.Console.WriteLine(x == null);
}
}";
var comp = CreateStandardCompilation(source, references: new[] { ValueTupleRef, SystemRuntimeFacadeRef });
comp.VerifyDiagnostics(
// (6,17): error CS8304: The first operand of an 'as' operator may not be a tuple literal without a natural type.
// var x = (0, null) as (int, T)?;
Diagnostic(ErrorCode.ERR_TypelessTupleInAs, "(0, null) as (int, T)?").WithLocation(6, 17)
);
}
}
}
\ No newline at end of file
src/Compilers/VisualBasic/Test/Emit/CodeGen/CodeGenTuples.vb
浏览文件 @
79b2bc6e
...
...
@@ -7863,6 +7863,336 @@ BC30512: Option Strict On disallows implicit conversions from 'Double' to 'Strin
End Sub
<Fact>
Public Sub TupleCTypeNullableConversionWithTypelessTuple()
Dim comp = CreateCompilationWithMscorlibAndVBRuntime(
<compilation>
<file name="a.vb"><![CDATA[
Option Strict On
Imports System
Class C
Shared Sub Main()
Dim x As (Integer, String)? = CType((1, Nothing), (Integer, String)?)
Console.Write(x)
End Sub
End Class
]]></file>
</compilation>, additionalRefs:=s_valueTupleRefs, options:=TestOptions.DebugExe)
comp.AssertNoDiagnostics()
CompileAndVerify(comp, expectedOutput:="(1, )")
Dim tree = comp.SyntaxTrees.Single()
Dim model = comp.GetSemanticModel(tree)
Dim node = tree.GetRoot().DescendantNodes().OfType(Of TupleExpressionSyntax)().Single()
Assert.Equal("(1, Nothing)", node.ToString())
Assert.Null(model.GetTypeInfo(node).Type)
Assert.Equal("System.Nullable(Of (System.Int32, System.String))", model.GetTypeInfo(node).ConvertedType.ToTestDisplayString())
Assert.Equal(ConversionKind.WideningNullableTuple, model.GetConversion(node).Kind)
Assert.Equal("System.Nullable(Of (System.Int32, System.String))", model.GetTypeInfo(node.Parent).Type.ToTestDisplayString())
Assert.Equal("System.Nullable(Of (System.Int32, System.String))", model.GetTypeInfo(node.Parent).ConvertedType.ToTestDisplayString())
End Sub
<Fact>
Public Sub TupleDirectCastNullableConversionWithTypelessTuple()
Dim comp = CreateCompilationWithMscorlibAndVBRuntime(
<compilation>
<file name="a.vb"><![CDATA[
Option Strict On
Imports System
Class C
Shared Sub Main()
Dim x As (Integer, String)? = DirectCast((1, Nothing), (Integer, String)?)
Console.Write(x)
End Sub
End Class
]]></file>
</compilation>, additionalRefs:=s_valueTupleRefs, options:=TestOptions.DebugExe)
comp.AssertNoDiagnostics()
CompileAndVerify(comp, expectedOutput:="(1, )")
Dim tree = comp.SyntaxTrees.Single()
Dim model = comp.GetSemanticModel(tree)
Dim node = tree.GetRoot().DescendantNodes().OfType(Of TupleExpressionSyntax)().Single()
Assert.Equal("(1, Nothing)", node.ToString())
Assert.Null(model.GetTypeInfo(node).Type)
Assert.Equal("System.Nullable(Of (System.Int32, System.String))", model.GetTypeInfo(node).ConvertedType.ToTestDisplayString())
Assert.Equal(ConversionKind.WideningNullableTuple, model.GetConversion(node).Kind)
Assert.Equal("System.Nullable(Of (System.Int32, System.String))", model.GetTypeInfo(node.Parent).Type.ToTestDisplayString())
Assert.Equal("System.Nullable(Of (System.Int32, System.String))", model.GetTypeInfo(node.Parent).ConvertedType.ToTestDisplayString())
End Sub
<Fact>
Public Sub TupleTryCastNullableConversionWithTypelessTuple()
Dim comp = CreateCompilationWithMscorlibAndVBRuntime(
<compilation>
<file name="a.vb"><![CDATA[
Option Strict On
Imports System
Class C
Shared Sub Main()
Dim x As (Integer, String)? = TryCast((1, Nothing), (Integer, String)?)
Console.Write(x)
End Sub
End Class
]]></file>
</compilation>, additionalRefs:=s_valueTupleRefs, options:=TestOptions.DebugExe)
comp.AssertTheseDiagnostics(<errors>
BC30792: 'TryCast' operand must be reference type, but '(Integer, String)?' is a value type.
Dim x As (Integer, String)? = TryCast((1, Nothing), (Integer, String)?)
~~~~~~~~~~~~~~~~~~
</errors>)
Dim tree = comp.SyntaxTrees.Single()
Dim model = comp.GetSemanticModel(tree)
Dim node = tree.GetRoot().DescendantNodes().OfType(Of TupleExpressionSyntax)().Single()
Assert.Equal("(1, Nothing)", node.ToString())
Assert.Null(model.GetTypeInfo(node).Type)
Assert.Equal("(System.Int32, System.Object)", model.GetTypeInfo(node).ConvertedType.ToTestDisplayString())
Assert.Equal(ConversionKind.WideningTuple, model.GetConversion(node).Kind)
Assert.Equal("System.Nullable(Of (System.Int32, System.String))", model.GetTypeInfo(node.Parent).Type.ToTestDisplayString())
Assert.Equal("System.Nullable(Of (System.Int32, System.String))", model.GetTypeInfo(node.Parent).ConvertedType.ToTestDisplayString())
End Sub
<Fact>
Public Sub TupleTryCastNullableConversionWithTypelessTuple2()
Dim comp = CreateCompilationWithMscorlibAndVBRuntime(
<compilation>
<file name="a.vb"><![CDATA[
Option Strict On
Imports System
Class C
Shared Sub M(Of T)()
Dim x = TryCast((0, Nothing), C(Of Integer, T))
Console.Write(x)
End Sub
End Class
Class C(Of T, U)
End Class
]]></file>
</compilation>, additionalRefs:=s_valueTupleRefs)
comp.AssertTheseDiagnostics(<errors>
BC30311: Value of type '(Integer, Object)' cannot be converted to 'C(Of Integer, T)'.
Dim x = TryCast((0, Nothing), C(Of Integer, T))
~~~~~~~~~~~~
</errors>)
Dim tree = comp.SyntaxTrees.Single()
Dim model = comp.GetSemanticModel(tree)
Dim node = tree.GetRoot().DescendantNodes().OfType(Of TupleExpressionSyntax)().Single()
Assert.Equal("(0, Nothing)", node.ToString())
Assert.Null(model.GetTypeInfo(node).Type)
Assert.Equal("(System.Int32, System.Object)", model.GetTypeInfo(node).ConvertedType.ToTestDisplayString())
Assert.Equal(ConversionKind.WideningTuple, model.GetConversion(node).Kind)
Assert.Equal("C(Of System.Int32, T)", model.GetTypeInfo(node.Parent).Type.ToTestDisplayString())
Assert.Equal("C(Of System.Int32, T)", model.GetTypeInfo(node.Parent).ConvertedType.ToTestDisplayString())
End Sub
<Fact>
Public Sub TupleImplicitNullableConversionWithTypelessTuple()
Dim comp = CreateCompilationWithMscorlibAndVBRuntime(
<compilation>
<file name="a.vb"><![CDATA[
Option Strict On
Class C
Shared Sub Main()
Dim x As (Integer, String)? = (1, Nothing)
System.Console.Write(x)
End Sub
End Class
]]></file>
</compilation>, additionalRefs:=s_valueTupleRefs, options:=TestOptions.DebugExe)
comp.AssertNoDiagnostics()
CompileAndVerify(comp, expectedOutput:="(1, )")
Dim tree = comp.SyntaxTrees.Single()
Dim model = comp.GetSemanticModel(tree)
Dim node = tree.GetRoot().DescendantNodes().OfType(Of TupleExpressionSyntax)().Single()
Assert.Equal("(1, Nothing)", node.ToString())
Assert.Null(model.GetTypeInfo(node).Type)
Assert.Equal("System.Nullable(Of (System.Int32, System.String))", model.GetTypeInfo(node).ConvertedType.ToTestDisplayString())
Assert.Equal(ConversionKind.WideningNullableTuple, model.GetConversion(node).Kind)
End Sub
<Fact>
Public Sub ImplicitConversionOnTypelessTupleWithUserConversion()
Dim comp = CreateCompilationWithMscorlibAndVBRuntime(
<compilation>
<file name="a.vb"><![CDATA[
Option Strict Off
Structure C
Shared Sub Main()
Dim x As C = (1, Nothing)
Dim y As C? = (2, Nothing)
End Sub
Public Shared Widening Operator CType(ByVal d As (Integer, String)) As C
Return New C()
End Operator
End Structure
]]></file>
</compilation>, additionalRefs:=s_valueTupleRefs, options:=TestOptions.DebugExe)
comp.AssertTheseDiagnostics(<errors>
BC30311: Value of type '(Integer, Object)' cannot be converted to 'C?'.
Dim y As C? = (2, Nothing)
~~~~~~~~~~~~
</errors>)
Dim tree = comp.SyntaxTrees.Single()
Dim model = comp.GetSemanticModel(tree)
Dim firstTuple = tree.GetRoot().DescendantNodes().OfType(Of TupleExpressionSyntax)().ElementAt(0)
Assert.Equal("(1, Nothing)", firstTuple.ToString())
Assert.Null(model.GetTypeInfo(firstTuple).Type)
Assert.Equal("C", model.GetTypeInfo(firstTuple).ConvertedType.ToTestDisplayString())
Assert.Equal(ConversionKind.Narrowing Or ConversionKind.UserDefined, model.GetConversion(firstTuple).Kind)
Dim secondTuple = tree.GetRoot().DescendantNodes().OfType(Of TupleExpressionSyntax)().ElementAt(1)
Assert.Equal("(2, Nothing)", secondTuple.ToString())
Assert.Null(model.GetTypeInfo(secondTuple).Type)
Assert.Equal("System.Nullable(Of C)", model.GetTypeInfo(secondTuple).ConvertedType.ToTestDisplayString())
Assert.Equal(ConversionKind.DelegateRelaxationLevelNone, model.GetConversion(secondTuple).Kind)
End Sub
<Fact>
Public Sub DirectCastOnTypelessTupleWithUserConversion()
Dim comp = CreateCompilationWithMscorlibAndVBRuntime(
<compilation>
<file name="a.vb"><![CDATA[
Option Strict Off
Structure C
Shared Sub Main()
Dim x = DirectCast((1, Nothing), C)
Dim y = DirectCast((2, Nothing), C?)
End Sub
Public Shared Widening Operator CType(ByVal d As (Integer, String)) As C
Return New C()
End Operator
End Structure
]]></file>
</compilation>, additionalRefs:=s_valueTupleRefs, options:=TestOptions.DebugExe)
comp.AssertTheseDiagnostics(<errors>
BC30311: Value of type '(Integer, Object)' cannot be converted to 'C'.
Dim x = DirectCast((1, Nothing), C)
~~~~~~~~~~~~
BC30311: Value of type '(Integer, Object)' cannot be converted to 'C?'.
Dim y = DirectCast((2, Nothing), C?)
~~~~~~~~~~~~
</errors>)
Dim tree = comp.SyntaxTrees.Single()
Dim model = comp.GetSemanticModel(tree)
Dim firstTuple = tree.GetRoot().DescendantNodes().OfType(Of TupleExpressionSyntax)().ElementAt(0)
Assert.Equal("(1, Nothing)", firstTuple.ToString())
Assert.Null(model.GetTypeInfo(firstTuple).Type)
Assert.Equal("(System.Int32, System.Object)", model.GetTypeInfo(firstTuple).ConvertedType.ToTestDisplayString())
Assert.Equal(ConversionKind.WideningTuple, model.GetConversion(firstTuple).Kind)
Dim secondTuple = tree.GetRoot().DescendantNodes().OfType(Of TupleExpressionSyntax)().ElementAt(1)
Assert.Equal("(2, Nothing)", secondTuple.ToString())
Assert.Null(model.GetTypeInfo(secondTuple).Type)
Assert.Equal("(System.Int32, System.Object)", model.GetTypeInfo(secondTuple).ConvertedType.ToTestDisplayString())
Assert.Equal(ConversionKind.WideningTuple, model.GetConversion(secondTuple).Kind)
End Sub
<Fact>
Public Sub TryCastOnTypelessTupleWithUserConversion()
Dim comp = CreateCompilationWithMscorlibAndVBRuntime(
<compilation>
<file name="a.vb"><![CDATA[
Option Strict Off
Structure C
Shared Sub Main()
Dim x = TryCast((1, Nothing), C)
Dim y = TryCast((2, Nothing), C?)
End Sub
Public Shared Widening Operator CType(ByVal d As (Integer, String)) As C
Return New C()
End Operator
End Structure
]]></file>
</compilation>, additionalRefs:=s_valueTupleRefs, options:=TestOptions.DebugExe)
comp.AssertTheseDiagnostics(<errors>
BC30792: 'TryCast' operand must be reference type, but 'C' is a value type.
Dim x = TryCast((1, Nothing), C)
~
BC30792: 'TryCast' operand must be reference type, but 'C?' is a value type.
Dim y = TryCast((2, Nothing), C?)
~~
</errors>)
Dim tree = comp.SyntaxTrees.Single()
Dim model = comp.GetSemanticModel(tree)
Dim firstTuple = tree.GetRoot().DescendantNodes().OfType(Of TupleExpressionSyntax)().ElementAt(0)
Assert.Equal("(1, Nothing)", firstTuple.ToString())
Assert.Null(model.GetTypeInfo(firstTuple).Type)
Assert.Equal("(System.Int32, System.Object)", model.GetTypeInfo(firstTuple).ConvertedType.ToTestDisplayString())
Assert.Equal(ConversionKind.WideningTuple, model.GetConversion(firstTuple).Kind)
Dim secondTuple = tree.GetRoot().DescendantNodes().OfType(Of TupleExpressionSyntax)().ElementAt(1)
Assert.Equal("(2, Nothing)", secondTuple.ToString())
Assert.Null(model.GetTypeInfo(secondTuple).Type)
Assert.Equal("(System.Int32, System.Object)", model.GetTypeInfo(secondTuple).ConvertedType.ToTestDisplayString())
Assert.Equal(ConversionKind.WideningTuple, model.GetConversion(secondTuple).Kind)
End Sub
<Fact>
Public Sub CTypeOnTypelessTupleWithUserConversion()
Dim comp = CreateCompilationWithMscorlibAndVBRuntime(
<compilation>
<file name="a.vb"><![CDATA[
Option Strict Off
Structure C
Shared Sub Main()
Dim x = CType((1, Nothing), C)
Dim y = CType((2, Nothing), C?)
End Sub
Public Shared Widening Operator CType(ByVal d As (Integer, String)) As C
Return New C()
End Operator
End Structure
]]></file>
</compilation>, additionalRefs:=s_valueTupleRefs, options:=TestOptions.DebugExe)
comp.AssertTheseDiagnostics(<errors>
BC30311: Value of type '(Integer, Object)' cannot be converted to 'C?'.
Dim y = CType((2, Nothing), C?)
~~~~~~~~~~~~
</errors>)
Dim tree = comp.SyntaxTrees.Single()
Dim model = comp.GetSemanticModel(tree)
Dim firstTuple = tree.GetRoot().DescendantNodes().OfType(Of TupleExpressionSyntax)().ElementAt(0)
Assert.Equal("(1, Nothing)", firstTuple.ToString())
Assert.Null(model.GetTypeInfo(firstTuple).Type)
Assert.Equal("(System.Int32, System.Object)", model.GetTypeInfo(firstTuple).ConvertedType.ToTestDisplayString())
Assert.Equal(ConversionKind.WideningTuple, model.GetConversion(firstTuple).Kind)
Dim secondTuple = tree.GetRoot().DescendantNodes().OfType(Of TupleExpressionSyntax)().ElementAt(1)
Assert.Equal("(2, Nothing)", secondTuple.ToString())
Assert.Null(model.GetTypeInfo(secondTuple).Type)
Assert.Equal("(System.Int32, System.Object)", model.GetTypeInfo(secondTuple).ConvertedType.ToTestDisplayString())
Assert.Equal(ConversionKind.WideningTuple, model.GetConversion(secondTuple).Kind)
End Sub
<Fact>
Public Sub TupleTargetTypeLambda()
...
...
@@ -8261,6 +8591,35 @@ End Module
End Sub
<Fact(Skip:="See bug 16697")>
<WorkItem(16697, "https://github.com/dotnet/roslyn/issues/16697")>
Public Sub GetSymbolInfo_01()
Dim source = "
Class C
Shared Sub Main()
Dim x1 = (Alice:=1, ""hello"")
Dim Alice = x1.Alice
End Sub
End Class
"
Dim tree = Parse(source, options:=TestOptions.Regular)
Dim comp = CreateCompilationWithMscorlib(tree)
Dim model = comp.GetSemanticModel(tree, ignoreAccessibility:=False)
Dim nodes = tree.GetCompilationUnitRoot().DescendantNodes()
Dim nc = nodes.OfType(Of NameColonEqualsSyntax)().ElementAt(0)
Dim sym = model.GetSymbolInfo(nc.Name)
Assert.Equal("Alice", sym.Symbol.Name)
Assert.Equal(SymbolKind.Field, sym.Symbol.Kind) ' Incorrectly returns Local
Assert.Equal(nc.Name.GetLocation(), sym.Symbol.Locations(0)) ' Incorrect location
End Sub
<Fact>
Public Sub RetargetTupleErrorType()
Dim libComp = CreateCompilationWithMscorlibAndVBRuntime(
...
...
src/EditorFeatures/VisualBasicTest/CodeActions/InlineTemporary/InlineTemporaryTests.vb
浏览文件 @
79b2bc6e
...
...
@@ -4397,6 +4397,29 @@ Class C
}
End Sub
End Class
"
Await
TestInRegularAndScriptAsync
(
code
,
expected
,
ignoreTrivia
:
=
False
)
End
Function
<
Fact
(
Skip
:
=
"InvalidCastException"
),
Trait
(
Traits
.
Feature
,
Traits
.
Features
.
CodeActionsInlineTemporary
)
>
<
WorkItem
(
16697
,
"https://github.com/dotnet/roslyn/issues/16697"
)
>
Public
Async
Function
TupleElementNameIsNotReplaced
()
As
Task
' The name of the named element has bad symbol info and gets replaced with (1 + 2)
Dim
code
=
"
Class C
Sub M()
Dim [||]i = 1 + 2
Dim t = (i, i:=3)
End Sub
End Class
"
Dim
expected
=
"
Class C
Sub M()
Dim t = (1 + 2, i:=3)
End Sub
End Class
"
Await
TestInRegularAndScriptAsync
(
code
,
expected
,
ignoreTrivia
:
=
False
)
End
Function
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录