提交 4483202b 编写于 作者: W Wonseok Chae

[EnC] Fix ArgumentException in SymbolMatcher

For a newly added type, there is no match in the previous generation but we were still looking for its match in some cases like array, type arguments and pointer. This fixes issue #1533.
上级 b2addcbb
......@@ -350,7 +350,11 @@ public override Symbol Visit(Symbol symbol)
public override Symbol VisitArrayType(ArrayTypeSymbol symbol)
{
var otherElementType = (TypeSymbol)this.Visit(symbol.ElementType);
Debug.Assert((object)otherElementType != null);
if (otherElementType == null)
{
// For a newly added type, there is no match in the previous generation, so it could be null.
return null;
}
var otherModifiers = VisitCustomModifiers(symbol.CustomModifiers);
return new ArrayTypeSymbol(_otherAssembly, otherElementType, otherModifiers, symbol.Rank);
}
......@@ -421,7 +425,11 @@ public override Symbol VisitNamedType(NamedTypeSymbol sourceType)
var otherTypeParameters = otherDef.GetAllTypeParameters();
var otherTypeArguments = typeArguments.SelectAsArray((t, v) => (TypeSymbol)v.Visit(t), this);
Debug.Assert(otherTypeArguments.All(t => (object)t != null));
if (otherTypeArguments.Any(t => (object)t == null))
{
// For a newly added type, there is no match in the previous generation, so it could be null.
return null;
}
// TODO: LambdaFrame has alpha renamed type parameters, should we rather fix that?
var typeMap = new TypeMap(otherTypeParameters, otherTypeArguments, allowAlpha: true);
......@@ -474,7 +482,11 @@ public override Symbol VisitParameter(ParameterSymbol parameter)
public override Symbol VisitPointerType(PointerTypeSymbol symbol)
{
var otherPointedAtType = (TypeSymbol)this.Visit(symbol.PointedAtType);
Debug.Assert((object)otherPointedAtType != null);
if (otherPointedAtType == null)
{
// For a newly added type, there is no match in the previous generation, so it could be null.
return null;
}
var otherModifiers = VisitCustomModifiers(symbol.CustomModifiers);
return new PointerTypeSymbol(otherPointedAtType, otherModifiers);
}
......
......@@ -9,6 +9,7 @@
using Microsoft.CodeAnalysis.CSharp.Test.Utilities;
using Microsoft.CodeAnalysis.CSharp.UnitTests;
using Microsoft.CodeAnalysis.Emit;
using Roslyn.Test.Utilities;
using Xunit;
namespace Microsoft.CodeAnalysis.CSharp.EditAndContinue.UnitTests
......@@ -188,5 +189,159 @@ public void CustomModifiers()
Assert.Equal(((PointerTypeSymbol)other.Parameters[0].Type).CustomModifiers.Length, 1);
Assert.Equal(((ArrayTypeSymbol)other.ReturnType).CustomModifiers.Length, 1);
}
[WorkItem(1533)]
[Fact]
public void PreviousType_ArrayType()
{
var source0 = @"
class C
{
static void M()
{
int x = 0;
}
class D {}
}";
var source1 = @"
class C
{
static void M()
{
D[] x = null;
}
class D {}
}";
var compilation0 = CreateCompilationWithMscorlib(source0, options: TestOptions.DebugDll);
var compilation1 = compilation0.WithSource(source1);
var matcher = new CSharpSymbolMatcher(
null,
compilation1.SourceAssembly,
default(EmitContext),
compilation0.SourceAssembly,
default(EmitContext),
null);
var elementType = compilation1.GetMember<TypeSymbol>("C.D");
var member = compilation1.CreateArrayTypeSymbol(elementType);
var other = matcher.MapReference((Cci.ITypeReference)member);
Assert.NotNull(other);
}
[WorkItem(1533)]
[Fact]
public void NoPreviousType_ArrayType()
{
var source0 = @"
class C
{
static void M()
{
int x = 0;
}
}";
var source1 = @"
class C
{
static void M()
{
D[] x = null;
}
class D {}
}";
var compilation0 = CreateCompilationWithMscorlib(source0, options: TestOptions.DebugDll);
var compilation1 = compilation0.WithSource(source1);
var matcher = new CSharpSymbolMatcher(
null,
compilation1.SourceAssembly,
default(EmitContext),
compilation0.SourceAssembly,
default(EmitContext),
null);
var elementType = compilation1.GetMember<TypeSymbol>("C.D");
var member = compilation1.CreateArrayTypeSymbol(elementType);
var other = matcher.MapReference((Cci.ITypeReference)member);
// For a newly added type, there is no match in the previous generation.
Assert.Null(other);
}
[WorkItem(1533)]
[Fact]
public void NoPreviousType_PointerType()
{
var source0 = @"
class C
{
static void M()
{
int x = 0;
}
}";
var source1 = @"
class C
{
static unsafe void M()
{
D* x = null;
}
struct D {}
}";
var compilation0 = CreateCompilationWithMscorlib(source0, options: TestOptions.DebugDll);
var compilation1 = compilation0.WithSource(source1);
var matcher = new CSharpSymbolMatcher(
null,
compilation1.SourceAssembly,
default(EmitContext),
compilation0.SourceAssembly,
default(EmitContext),
null);
var elementType = compilation1.GetMember<TypeSymbol>("C.D");
var member = compilation1.CreatePointerTypeSymbol(elementType);
var other = matcher.MapReference((Cci.ITypeReference)member);
// For a newly added type, there is no match in the previous generation.
Assert.Null(other);
}
[WorkItem(1533)]
[Fact]
public void NoPreviousType_GenericType()
{
var source0 = @"
using System.Collections.Generic;
class C
{
static void M()
{
int x = 0;
}
}";
var source1 = @"
using System.Collections.Generic;
class C
{
static void M()
{
List<D> x = null;
}
class D {}
List<D> y;
}";
var compilation0 = CreateCompilationWithMscorlib(source0, options: TestOptions.DebugDll);
var compilation1 = compilation0.WithSource(source1);
var matcher = new CSharpSymbolMatcher(
null,
compilation1.SourceAssembly,
default(EmitContext),
compilation0.SourceAssembly,
default(EmitContext),
null);
var member = compilation1.GetMember<FieldSymbol>("C.y");
var other = matcher.MapReference((Cci.ITypeReference)member.Type);
// For a newly added type, there is no match in the previous generation.
Assert.Null(other);
}
}
}
......@@ -284,7 +284,10 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.Emit
Public Overrides Function VisitArrayType(symbol As ArrayTypeSymbol) As Symbol
Dim otherElementType As TypeSymbol = DirectCast(Me.Visit(symbol.ElementType), TypeSymbol)
Debug.Assert(otherElementType IsNot Nothing)
If otherElementType Is Nothing Then
' For a newly added type, there is no match in the previous generation, so it could be Nothing.
Return Nothing
End If
Dim otherModifiers = VisitCustomModifiers(symbol.CustomModifiers)
Return New ArrayTypeSymbol(otherElementType, otherModifiers, symbol.Rank, Me._otherAssembly)
End Function
......@@ -341,7 +344,10 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.Emit
Dim otherTypeParameters As ImmutableArray(Of TypeParameterSymbol) = otherDef.GetAllTypeParameters()
Dim otherTypeArguments As ImmutableArray(Of TypeSymbol) = typeArguments.SelectAsArray(Function(t, v) DirectCast(v.Visit(t), TypeSymbol), Me)
Debug.Assert(otherTypeArguments.All(Function(t) t IsNot Nothing))
If otherTypeArguments.Any(Function(t) t Is Nothing) Then
' For a newly added type, there is no match in the previous generation, so it could be Nothing.
Return Nothing
End If
Dim typeMap = TypeSubstitution.Create(otherDef, otherTypeParameters, otherTypeArguments, False)
Return otherDef.Construct(typeMap)
......
......@@ -161,6 +161,7 @@
<Compile Include="Emit\EditAndContinue\EditAndContinueStateMachineTests.vb" />
<Compile Include="Emit\EditAndContinue\EditAndContinueTestBase.vb" />
<Compile Include="Emit\EditAndContinue\EditAndContinueTests.vb" />
<Compile Include="Emit\EditAndContinue\SymbolMatcherTests.vb" />
<Compile Include="Emit\EmitCustomModifiers.vb" />
<Compile Include="Emit\EmitErrorTests.vb" />
<Compile Include="Emit\EmitMetadata.vb" />
......
' Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
Imports System.Collections.Immutable
Imports Microsoft.CodeAnalysis.CodeGen
Imports Microsoft.CodeAnalysis.Emit
Imports Microsoft.CodeAnalysis.Test.Utilities
Imports Microsoft.CodeAnalysis.VisualBasic.Symbols
Imports Microsoft.CodeAnalysis.VisualBasic.Emit
Imports Roslyn.Test.Utilities
Namespace Microsoft.CodeAnalysis.VisualBasic.UnitTests
Public Class SymbolMatcherTests
Inherits EditAndContinueTestBase
<WorkItem(1533)>
<Fact>
Public Sub PreviousType_ArrayType()
Dim sources0 = <compilation>
<file name="a.vb"><![CDATA[
Class C
Shared Sub M()
Dim x As Integer = 0
End Sub
Class D : End Class
End Class
]]></file>
</compilation>
Dim sources1 = <compilation>
<file name="a.vb"><![CDATA[
Class C
Shared Sub M()
Dim x() As D = Nothing
End Sub
Class D : End Class
End Class
]]></file>
</compilation>
Dim compilation0 = CreateCompilationWithMscorlib(sources0, TestOptions.DebugDll)
Dim compilation1 = compilation0.WithSource(sources1)
Dim matcher = New VisualBasicSymbolMatcher(
Nothing,
compilation1.SourceAssembly,
Nothing,
compilation0.SourceAssembly,
Nothing,
Nothing)
Dim elementType = compilation1.GetMember(Of TypeSymbol)("C.D")
Dim member = compilation1.CreateArrayTypeSymbol(elementType)
Dim other = matcher.MapReference(member)
Assert.NotNull(other)
End Sub
<WorkItem(1533)>
<Fact>
Public Sub NoPreviousType_ArrayType()
Dim sources0 = <compilation>
<file name="a.vb"><![CDATA[
Class C
Shared Sub M()
Dim x As Integer = 0
End Sub
End Class
]]></file>
</compilation>
Dim sources1 = <compilation>
<file name="a.vb"><![CDATA[
Class C
Shared Sub M()
Dim x() As D = Nothing
End Sub
Class D : End Class
End Class
]]></file>
</compilation>
Dim compilation0 = CreateCompilationWithMscorlib(sources0, TestOptions.DebugDll)
Dim compilation1 = compilation0.WithSource(sources1)
Dim matcher = New VisualBasicSymbolMatcher(
Nothing,
compilation1.SourceAssembly,
Nothing,
compilation0.SourceAssembly,
Nothing,
Nothing)
Dim elementType = compilation1.GetMember(Of TypeSymbol)("C.D")
Dim member = compilation1.CreateArrayTypeSymbol(elementType)
Dim other = matcher.MapReference(member)
' For a newly added type, there is no match in the previous generation.
Assert.Null(other)
End Sub
<WorkItem(1533)>
<Fact>
Public Sub NoPreviousType_GenericType()
Dim sources0 = <compilation>
<file name="a.vb"><![CDATA[
Imports System.Collections.Generic
Class C
Shared Sub M()
Dim x As Integer = 0
End Sub
End Class
]]></file>
</compilation>
Dim sources1 = <compilation>
<file name="a.vb"><![CDATA[
Imports System.Collections.Generic
Class C
Shared Sub M()
Dim x As List(Of D) = Nothing
End Sub
Class D : End Class
Dim y As List(Of D)
End Class
]]></file>
</compilation>
Dim compilation0 = CreateCompilationWithMscorlib(sources0, TestOptions.DebugDll)
Dim compilation1 = compilation0.WithSource(sources1)
Dim matcher = New VisualBasicSymbolMatcher(
Nothing,
compilation1.SourceAssembly,
Nothing,
compilation0.SourceAssembly,
Nothing,
Nothing)
Dim member = compilation1.GetMember(Of FieldSymbol)("C.y")
Dim other = matcher.MapReference(DirectCast(member.Type, Cci.ITypeReference))
' For a newly added type, there is no match in the previous generation.
Assert.Null(other)
End Sub
End Class
End Namespace
\ No newline at end of file
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册