Skip to content

CheckTupleElementNames throws error for missing tuple element.#29042

Merged
chborl merged 6 commits intodotnet:dev15.8.xfrom
chborl:watson
Aug 7, 2018
Merged

CheckTupleElementNames throws error for missing tuple element.#29042
chborl merged 6 commits intodotnet:dev15.8.xfrom
chborl:watson

Conversation

@chborl
Copy link
Copy Markdown
Contributor

@chborl chborl commented Aug 2, 2018

Customer scenario

Type the following in editor window

class C
{
    void M()
    {
        (a, ) = (
    }
}

Put caret at the opening parenthesis on the right side of the assignment statement and invoke Signature Helper (Ctrl+Shift+space)

Actual:
CheckTupleElementNames throws error CodeAnalysisResource.TupleElementNameEmpty

Expected:
No error thrown

Bugs this fixes

Fixes: https://devdiv.visualstudio.com/DevDiv/_workitems/edit/655607

Workarounds, if any

none

Risk

None

Performance impact

None

Is this a regression from a previous update?

No

Root cause analysis

Original code did not account for missing tuple element

How was the bug found?

Watson

Test documentation updated?

New unit test added

@chborl chborl added the PR For Personal Review Only The PR doesn’t require anyone other than the developer to review it. label Aug 2, 2018
@chborl chborl requested review from a team as code owners August 2, 2018 23:29
@chborl chborl removed the PR For Personal Review Only The PR doesn’t require anyone other than the developer to review it. label Aug 3, 2018
@chborl
Copy link
Copy Markdown
Contributor Author

chborl commented Aug 3, 2018

@CyrusNajmabadi , @jcouv , since tuple element names are optional, I don't think TupleElementNameEmpty should be enforced. Thoughts?

@chborl chborl changed the title WIP - Watson bug investigation CheckTupleElementNames throws error for missing tuple element. Aug 3, 2018
@chborl
Copy link
Copy Markdown
Contributor Author

chborl commented Aug 3, 2018

Also @heejaechang , do you think this fix is viable?

@jcouv
Copy link
Copy Markdown
Member

jcouv commented Aug 3, 2018

I don't think we should relax this check. If the IDE needs to provide only some names, I think passing null for those would work.
If that didn't work, another option would be to use Item<n>.

@jcouv jcouv self-assigned this Aug 3, 2018
Copy link
Copy Markdown
Contributor

@heejaechang heejaechang Aug 3, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this check feels real bit strange to me. so null or "+" is okay but "" not okay?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ping @jcouv

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would check for string.IsNullOrWhitespace(...) ? null : xxx

@chborl
Copy link
Copy Markdown
Contributor Author

chborl commented Aug 4, 2018

@jcouv , passing null works.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It feels like such a helper method is likely to already exist. Can you double-check?

Copy link
Copy Markdown
Member

@jcouv jcouv left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM (iteration 4), but please confirm there isn't already a helper method to check for whitespace/newlines. Thanks

Copy link
Copy Markdown
Contributor

@CyrusNajmabadi CyrusNajmabadi Aug 6, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fwiw @jcouv . i do find it odd that there is this restriction in the core API. i.e. you allow null. you allow whitespace. you allow normal text. but you basically don't allow the empty string. seems... string to me. But if you really want that, then this change seems ok :)

@chborl small nit. could you just make this:

else if (expr is IdentifierName name) { ...

Then you don't need the multiple casts.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@chborl since 'null' is allowed, this check should be:

elementNamesBuilder.Add(name.Identifier.ValueText == "" ? null : name.Identifier.ValueText)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@CyrusNajmabadi I agree the restriction is a bit strange, but arguably this PR demonstrates why it is useful: it helps guide users to pass null rather than empty, when they want to represent missing names ;-)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@jcouv so whitespace is also okay? just not empty string? is empty string used as some kind of special state marker? is that why empty string is explicitly blocked?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@jcouv asking since I saw Chery changed back from IsNullOrWhitespace to checking explicitly just "" string.

will null or whitespaces input will change any outcome of the API?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Correct, you can create a tuple symbol with illegal names, but we block empty strings.

This check was added in PR #14958
The most relevant comment I could find is that "fields can't have blank names".

This was tested explicitly:

        [Fact]
        public void CreateTupleTypeSymbol2_BadNames()
        {
            var comp = CSharpCompilation.Create("test", references: new[] { MscorlibRef });

            ITypeSymbol intType = comp.GetSpecialType(SpecialType.System_Int32);

            // illegal C# identifiers and blank
            var tuple2 = comp.CreateTupleTypeSymbol(ImmutableArray.Create(intType, intType), ImmutableArray.Create("123", " "));
            Assert.Equal(new[] { "123", " " }, GetTupleElementNames(tuple2));

            // reserved identifiers
            var tuple3 = comp.CreateTupleTypeSymbol(ImmutableArray.Create(intType, intType), ImmutableArray.Create("return", "class"));
            Assert.Equal(new[] { "return", "class" }, GetTupleElementNames(tuple3));
        }

Copy link
Copy Markdown
Contributor

@CyrusNajmabadi CyrusNajmabadi left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Close. but needs a little refinement. Thanks!

@chborl chborl merged commit d4a72e6 into dotnet:dev15.8.x Aug 7, 2018
@chborl chborl deleted the watson branch October 26, 2018 17:18
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants