public static void Equals(string namespaceName) { var syntaxTree = CSharpSyntaxTree.ParseText( @" namespace N { }".AssertReplace("N", namespaceName)); var compilation = CSharpCompilation.Create("test", new[] { syntaxTree }); var semanticModel = compilation.GetSemanticModel(syntaxTree); var declaration = syntaxTree.Find <NamespaceDeclarationSyntax>(namespaceName); var symbol = semanticModel.GetDeclaredSymbol(declaration, CancellationToken.None); Assert.AreEqual(true, NamespaceSymbolComparer.Equals(symbol, namespaceName)); }
internal static bool IsValueValidForRegisteredType(ExpressionSyntax value, ITypeSymbol registeredType, SemanticModel semanticModel, CancellationToken cancellationToken, PooledSet <SyntaxNode>?visited = null) { switch (value) { case ConditionalExpressionSyntax conditional: return(IsValueValidForRegisteredType(conditional.WhenTrue, registeredType, semanticModel, cancellationToken, visited) && IsValueValidForRegisteredType(conditional.WhenFalse, registeredType, semanticModel, cancellationToken, visited)); case BinaryExpressionSyntax binary when binary.IsKind(SyntaxKind.CoalesceExpression): return(IsValueValidForRegisteredType(binary.Left, registeredType, semanticModel, cancellationToken, visited) && IsValueValidForRegisteredType(binary.Right, registeredType, semanticModel, cancellationToken, visited)); } if (registeredType.TypeKind == TypeKind.Enum) { return(semanticModel.TryGetType(value, cancellationToken, out var valueType) && valueType.MetadataName == registeredType.MetadataName && Equals(valueType.ContainingType, registeredType.ContainingType) && NamespaceSymbolComparer.Equals(valueType.ContainingNamespace, registeredType.ContainingNamespace)); } if (semanticModel.IsRepresentationPreservingConversion(value, registeredType)) { return(true); } if (semanticModel.TryGetSymbol(value, cancellationToken, out var symbol)) { if (symbol is IFieldSymbol field) { if (field.TrySingleDeclaration(cancellationToken, out var fieldDeclaration)) { if (fieldDeclaration.Declaration is { } variableDeclaration&& variableDeclaration.Variables.TryLast(out var variable) && variable.Initializer is { } initializer&& !IsValueValidForRegisteredType(initializer.Value, registeredType, semanticModel, cancellationToken, visited)) { return(false); } return(IsAssignedValueOfRegisteredType(symbol, fieldDeclaration)); } return(field.Type == KnownSymbols.Object); } if (symbol is IPropertySymbol property) { if (property.TrySingleDeclaration(cancellationToken, out PropertyDeclarationSyntax? propertyDeclaration)) { if (propertyDeclaration.Initializer is { } initializer&& !IsValueValidForRegisteredType(initializer.Value, registeredType, semanticModel, cancellationToken, visited)) { return(false); } if (property.SetMethod == null && property.GetMethod is { } getMethod) { return(IsReturnValueOfRegisteredType(getMethod)); } return(IsAssignedValueOfRegisteredType(symbol, propertyDeclaration)); } return(property.Type == KnownSymbols.Object); } if (symbol is IMethodSymbol method) { return(IsReturnValueOfRegisteredType(method)); } } return(false); bool IsAssignedValueOfRegisteredType(ISymbol memberSymbol, MemberDeclarationSyntax declaration) { if (declaration.TryFirstAncestor(out TypeDeclarationSyntax? typeDeclaration)) { using (var walker = AssignmentExecutionWalker.For(memberSymbol, typeDeclaration, SearchScope.Type, semanticModel, cancellationToken)) { foreach (var assignment in walker.Assignments) { if (!IsValueValidForRegisteredType(assignment.Right, registeredType, semanticModel, cancellationToken, visited)) { return(false); } } } } return(true); } bool IsReturnValueOfRegisteredType(IMethodSymbol method) { if (method.TrySingleMethodDeclaration(cancellationToken, out var target)) { #pragma warning disable IDISP003 // Dispose previous before re-assigning. using (visited = visited.IncrementUsage()) #pragma warning restore IDISP003 // Dispose previous before re-assigning. { if (visited.Add(target)) { using (var walker = ReturnValueWalker.Borrow(target)) { foreach (var returnValue in walker.ReturnValues) { if (!IsValueValidForRegisteredType(returnValue, registeredType, semanticModel, cancellationToken, visited)) { return(false); } } } } return(true); } } return(method.ReturnType == KnownSymbols.Object); } }