How to determine that a partial method has no implementation

Given the case:

partial class Test
{
    partial void FooBar();
}

partial class Test
{
    public void Foo()
    {
        FooBar();
    }
}

Now getting SymbolInfofrom the call FooBar()gives me IMethodSymbolwhere PartialDefinitionPart == nulland PartialImplementationPart == null. Is there a way to determine if a partial implementation is missing?

+4
source share
3 answers

The XML documentation for PartialDefinitionPartsays:

If it is part of the partial method implementation, returns the corresponding part of the definition. Otherwise null.

And PartialImplementationPart:

If it is a declaration of a partial method without a body, and this method is implemented with a body, returns this definition of implementation. Otherwise, zero.

, , , null PartialImplementationPart. , , , , .

+3

<

  • partial (MethodDeclarationSyntax.Modifiers)
  • ( svicks) IMethodSymbol.PartialDefinitionPart
  • IMethodSymbol.PartialImplementationPart .

, :

foreach (var project in solution.Projects)
{
    foreach (var document in project.Documents)
    {
        var methods = document
            .GetSyntaxRootAsync().Result
            .DescendantNodes()
            .OfType<MethodDeclarationSyntax>()
            .ToList();

        var semanticModel = document.GetSemanticModelAsync().Result;
        foreach (var method in methods)
        {
            if (method.Modifiers.All(m => m.ValueText != "partial"))
                continue;

            var methodSymbol = semanticModel.GetDeclaredSymbol(method);
            if (methodSymbol.PartialDefinitionPart == null 
                && methodSymbol.PartialImplementationPart == null)
            {
                // found partial method without an implementation!
            }
        }
    }
}

, , , , , , , .

0

I myself coded this method using the syntax link in IMethodSymbolwhen I tried to find it and found the implementation of golub roslyn in this problem [1]. This version did not work for me, as I found that it DeclaringSyntaxReferencescontains only one element, even if the partial method has a body. I fixed it like this:

    public static bool IsPartialMethod(this IMethodSymbol method, out bool hasEmptyBody)
    {
        if (method.IsDefinedInMetadata())
        {
            hasEmptyBody = false;
            return false;
        }

        foreach (var reference in method.DeclaringSyntaxReferences)
        {
            var syntax = reference.GetSyntax();
            if (syntax.Kind() != SyntaxKind.MethodDeclaration)
                continue;

            var node = syntax as MethodDeclarationSyntax;
            if (!node.Modifiers.Any(SyntaxKind.PartialKeyword))
            {
                hasEmptyBody = false;
                return false;
            }
        }

        hasEmptyBody = method.PartialImplementationPart == null || method.PartialDefinitionPart != null;
        return true;
    }

    /// <returns>False if it not defined in source</returns>
    public static bool IsDefinedInMetadata(this ISymbol symbol)
    {
        return symbol.Locations.Any(loc => loc.IsInMetadata);
    }

[1] https://github.com/dotnet/roslyn/issues/48#issuecomment-75641847

0
source

Source: https://habr.com/ru/post/1536208/


All Articles