|
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
#nullable disable
using System.Linq;
using Microsoft.CodeAnalysis.CSharp.Symbols;
using Microsoft.CodeAnalysis.CSharp.Syntax;
using Microsoft.CodeAnalysis.CSharp.Test.Utilities;
using Xunit;
namespace Microsoft.CodeAnalysis.CSharp.UnitTests
{
public class UpdatedContainingSymbolAndNullableAnnotationTests : CSharpTestBase
{
[Fact]
public void LocalSymbols()
{
var source = @"
class C
{
void M()
{
object local1;
object? local2;
}
void M2() {}
}";
var comp = CreateCompilation(source, options: WithNullableEnable());
var syntaxTree = comp.SyntaxTrees[0];
var root = syntaxTree.GetRoot();
var model = comp.GetSemanticModel(syntaxTree);
var varDeclarators = root.DescendantNodes().OfType<VariableDeclaratorSyntax>();
var local1 = model.GetDeclaredSymbol(varDeclarators.First()).GetSymbol<SourceLocalSymbol>();
var local2 = model.GetDeclaredSymbol(varDeclarators.ElementAt(1)).GetSymbol<SourceLocalSymbol>();
// Using a different method as the parent is an accurate enough simulation for these tests of equality.
Symbol m2 = model.GetDeclaredSymbol(root.DescendantNodes().OfType<MethodDeclarationSyntax>().ElementAt(1)).GetSymbol();
var wrappedLocal1 = UpdatedContainingSymbolAndNullableAnnotationLocal.CreateForTest(local1, m2, TypeWithAnnotations.Create(local1.Type, NullableAnnotation.Annotated));
var wrappedLocal1a = UpdatedContainingSymbolAndNullableAnnotationLocal.CreateForTest(local1, m2, TypeWithAnnotations.Create(local1.Type, NullableAnnotation.Annotated));
var wrappedLocal2 = UpdatedContainingSymbolAndNullableAnnotationLocal.CreateForTest(local2, m2, TypeWithAnnotations.Create(local1.Type, NullableAnnotation.NotAnnotated));
assertEquality(local1, local1, nullableIgnored: true, considerEverything: true);
assertEquality(local1, wrappedLocal1, nullableIgnored: true, considerEverything: false);
assertEquality(local1, local2, nullableIgnored: false, considerEverything: false);
assertEquality(wrappedLocal1, local2, nullableIgnored: false, considerEverything: false);
assertEquality(wrappedLocal1, wrappedLocal2, nullableIgnored: false, considerEverything: false);
assertEquality(wrappedLocal1, wrappedLocal1, nullableIgnored: true, considerEverything: true);
assertEquality(wrappedLocal1, wrappedLocal1a, nullableIgnored: true, considerEverything: true);
void assertEquality(Symbol symbol1, Symbol symbol2, bool nullableIgnored, bool considerEverything)
{
if (considerEverything)
{
Assert.True(nullableIgnored, "If considerEverything is true, nullableIgnored should be true as well.");
}
Assert.Equal(nullableIgnored, symbol1.Equals(symbol2));
Assert.Equal(nullableIgnored, symbol2.Equals(symbol1));
if (nullableIgnored)
{
Assert.Equal(symbol1.GetHashCode(), symbol2.GetHashCode());
}
Assert.Equal(nullableIgnored, symbol1.Equals(symbol2, TypeCompareKind.AllNullableIgnoreOptions));
Assert.Equal(nullableIgnored, symbol2.Equals(symbol1, TypeCompareKind.AllNullableIgnoreOptions));
Assert.Equal(considerEverything, symbol1.Equals(symbol2, TypeCompareKind.ConsiderEverything2));
Assert.Equal(considerEverything, symbol2.Equals(symbol1, TypeCompareKind.ConsiderEverything2));
}
}
}
}
|