dotnet/roslyn

NullReferenceException is thrown by IPropertyReferenceOperation.Arguments obtained from ImplicitElementAccessSyntax

Open

#41,229 opened on Jan 27, 2020

View on GitHub
 (0 comments) (0 reactions) (0 assignees)C# (4,257 forks)batch import
Area-CompilersBughelp wanted

Repository metrics

Stars
 (20,414 stars)
PR merge metrics
 (Avg merge 6d 17h) (256 merged PRs in 30d)

Description

When trying to get the arguments of the property reference operation from the implicit indexer access inside of an object initializer:

using System;
using System.Collections.Generic;
using System.Linq;  

using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp;
using Microsoft.CodeAnalysis.CSharp.Syntax;
using Microsoft.CodeAnalysis.Operations;

class Program
{
    static void Main(string[] args)
    {
        string sourceCode = @"
using System;      

namespace Test
{
    class C
    {
        string val = """";

        // Write-only indexer with default parameter.
        public string this[string s1, string s2 = """"]
        {                         
            set
            {
                val = s1 + s2 + value;
            }                    
        }    
    }

    class Program
    {
        static void Main(string[] args)
        {
            var c = new C()
            {
                [""a"", ""b""] = ""c"",             // OK
                [s1: ""qw"", s2: ""er""] = ""11"",  // OK
                [s1: ""ty"", ""ui""] = ""22"",      // OK
                [""z""] = ""x"",                    // NOT OK
                [s2: ""c"", s1: ""v""] = ""m""      // NOT OK
            };        
        }
    }
}            
        ";

        SyntaxTree tree = CSharpSyntaxTree.ParseText(sourceCode);  
        var csComp = CSharpCompilation.Create("", new List<SyntaxTree>() { tree });
        SemanticModel model = csComp.GetSemanticModel(tree);

        var nodes = tree.GetRoot().DescendantNodes().OfType<ImplicitElementAccessSyntax>();

        foreach (var node in nodes)
        {                               
            IOperation operation = model.GetOperation(node);
            var propRefOp = (IPropertyReferenceOperation)operation;

            // Here, an exception is thrown when attempting to retrieve the operation's "Arguments".
            foreach (var arg in propRefOp.Arguments)
            {
                Console.Write(arg.Syntax.ToString() + ", ");
            }
            Console.WriteLine();
        }
    }
}

i get the System.NullReferenceException: 'Object reference not set to an instance of an object.':

   at Microsoft.CodeAnalysis.CSharp.LocalRewriter.AppendMissingOptionalArguments(CSharpOperationFactory operationFactory, SyntaxNode syntax, Symbol methodOrIndexer, MethodSymbol optionalParametersMethod, Boolean expanded, Binder binder, ArrayBuilder`1 missingParameters, ArrayBuilder`1 argumentsBuilder) in /_/src/Compilers/CSharp/Portable/Lowering/LocalRewriter/LocalRewriter_Call.cs:line 1132
   at Microsoft.CodeAnalysis.CSharp.LocalRewriter.BuildArgumentsInEvaluationOrder(CSharpOperationFactory operationFactory, SyntaxNode syntax, Symbol methodOrIndexer, MethodSymbol optionalParametersMethod, Boolean expanded, ImmutableArray`1 argsToParamsOpt, ImmutableArray`1 arguments, Binder binder) in /_/src/Compilers/CSharp/Portable/Lowering/LocalRewriter/LocalRewriter_Call.cs:line 832
   at Microsoft.CodeAnalysis.CSharp.LocalRewriter.MakeArgumentsInEvaluationOrder(CSharpOperationFactory operationFactory, Binder binder, SyntaxNode syntax, ImmutableArray`1 arguments, Symbol methodOrIndexer, MethodSymbol optionalParametersMethod, Boolean expanded, ImmutableArray`1 argsToParamsOpt, Boolean invokedAsExtensionMethod) in /_/src/Compilers/CSharp/Portable/Lowering/LocalRewriter/LocalRewriter_Call.cs:line 618
   at Microsoft.CodeAnalysis.Operations.CSharpOperationFactory.DeriveArguments(BoundNode boundNode, Binder binder, Symbol methodOrIndexer, MethodSymbol optionalParametersMethod, ImmutableArray`1 boundArguments, ImmutableArray`1 argumentNamesOpt, ImmutableArray`1 argumentsToParametersOpt, ImmutableArray`1 argumentRefKindsOpt, ImmutableArray`1 parameters, Boolean expanded, SyntaxNode invocationSyntax, Boolean invokedAsExtensionMethod) in /_/src/Compilers/CSharp/Portable/Operations/CSharpOperationFactory_Methods.cs:line 337
   at Microsoft.CodeAnalysis.Operations.CSharpOperationFactory.DeriveArguments(BoundNode containingExpression, Boolean isObjectOrCollectionInitializer) in /_/src/Compilers/CSharp/Portable/Operations/CSharpOperationFactory_Methods.cs:line 222
   at Microsoft.CodeAnalysis.Operations.CSharpLazyPropertyReferenceOperation.CreateArguments() in /_/src/Compilers/CSharp/Portable/Operations/CSharpOperationNodes.cs:line 1123
   at Microsoft.CodeAnalysis.Operations.LazyPropertyReferenceOperation.get_Arguments() in /_/src/Compilers/Core/Portable/Generated/Operations.Generated.cs:line 4332
   at Test.Program.Main(String[] args) in C:\Workspace\Test\Test\Program.cs:line 64

An exception is only thrown when arguments of indexer access are not placed in the right order, or there are missing optional arguments in the source code. All other cases seem to work fine.

Contributor guide