public static void Equal(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.Equal(symbol, symbol));
        }
Ejemplo n.º 2
0
        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);
            }
        }
Ejemplo n.º 3
0
        private static int GenerateDeclarations(GenerateDeclarationsCommandLineOptions options)
        {
            if (!TryParseIgnoredDeclarationListParts(options.IgnoredParts, out DeclarationListParts ignoredParts))
            {
                return(1);
            }

            if (!TryParseVisibility(options.Visibility, out Visibility visibility))
            {
                return(1);
            }

            DocumentationModel documentationModel = CreateDocumentationModel(options.References, options.Assemblies, visibility, options.AdditionalXmlDocumentation);

            if (documentationModel == null)
            {
                return(1);
            }

            var declarationListOptions = new DeclarationListOptions(
                ignoredNames: options.IgnoredNames,
                indent: !options.NoIndent,
                indentChars: options.IndentChars,
                nestNamespaces: options.NestNamespaces,
                newLineBeforeOpenBrace: !options.NoNewLineBeforeOpenBrace,
                emptyLineBetweenMembers: options.EmptyLineBetweenMembers,
                formatBaseList: options.FormatBaseList,
                formatConstraints: options.FormatConstraints,
                formatParameters: options.FormatParameters,
                splitAttributes: !options.MergeAttributes,
                includeAttributeArguments: !options.OmitAttributeArguments,
                omitIEnumerable: !options.IncludeIEnumerable,
                useDefaultLiteral: !options.NoDefaultLiteral,
                fullyQualifiedNames: options.FullyQualifiedNames,
                depth: options.Depth,
                ignoredParts: ignoredParts);

            var cts = new CancellationTokenSource();

            Console.CancelKeyPress += (sender, e) =>
            {
                e.Cancel = true;
                cts.Cancel();
            };

            CancellationToken cancellationToken = cts.Token;

            WriteLine($"Declaration list is being generated to '{options.OutputPath}'.", Verbosity.Minimal);

            Task <string> task = DeclarationListGenerator.GenerateAsync(
                documentationModel,
                declarationListOptions,
                namespaceComparer: NamespaceSymbolComparer.GetInstance(systemNamespaceFirst: !options.NoPrecedenceForSystem),
                cancellationToken: cancellationToken);

            string content = task.Result;

            string path = options.OutputPath;

            Directory.CreateDirectory(Path.GetDirectoryName(path));
            File.WriteAllText(path, content, Encoding.UTF8);

            WriteLine($"Declaration list successfully generated to '{options.OutputPath}'.", Verbosity.Minimal);

            return(0);
        }