Roslyn: Code fix to generate local function

Created on 21 Jul 2018  路  6Comments  路  Source: dotnet/roslyn

It would be nice to have one similar to "generate method".

I propose that the function is created at the end of the containing method/member/accessor, unless we're already in a local function, in which case the new function should be generated below the current one. Expression bodies should be expanded to blocks if necessary.

Examples:

  • simple case: generate at the end of the method
    ```c#
    class C
    {
    int M()
    {
    if (true)
    {
    Foo("");
    }

    return 0;
    

    }
    }

```c#
using System;

class C
{
    int M()
    {
        if (true)
        {
            Foo("");
        }

        return 0;

        void Foo(string v)
        {
            throw new NotImplementedException();
        }
    }
}
  • inside local function, so generate below the innermost local function
  • the fact that we're in a lambda has no effect on the analysis
    ```c#
    using System;

class C
{
void M()
{
if (true)
{
void A()
{
Action a = () => Foo();
}

        void B()
        {
        }
    }
}

}

```c#
using System;

class C
{
    void M()
    {
        if (true)
        {
            void A()
            {
                Action a = () => Foo();
            }

            void Foo()
            {
                throw new NotImplementedException();
            }

            void B()
            {
            }
        }
    }
}

  • expression bodied property expanded
    ```c#
    using System;

class C
{
int TakeFunc(Func f) => f();

int P => TakeFunc(Foo);

}

```c#
using System;

class C
{
    int TakeFunc(Func<int> f) => f();

    int P
    {
        get
        {
            return TakeFunc(Foo);

            int Foo()
            {
                throw new NotImplementedException();
            }
        }
    }
}
Area-IDE Feature Request help wanted

All 6 comments

The placement of local functions comes down to preference, so I'd be curious as to what others think about these rules. This is just an idea and the final design is not up to me obviously :smile:

Seems reasonable to me. I think it's ok for us to take an opinionated stance toward 'end of method'. It is at least something that can explained reasonably. i.e. "by placing at end of function, it does not interfere with understanding the direct code flow of the actual method you're in."

Design Meeting Notes

  • Generating the local function at the bottom of the current member sounds good (without an option for now).
  • Move member within type can hopefully provide an easy fix-up if that wasn't the desired location of the local function. (FYI @gundermanc)

@dpoeschl Thanks. Is it also OK that if we're generating from inside an existing local function, we would generate below the current local function, as opposed to at the bottom?

Move member within type can provide an easy fix-up if that wasn't the desired location of the local function. (FYI @gundermanc)

Is this something that exists today?

@Neme12

Is it also OK that if we're generating from inside an existing local function, we would generate below the current local function, as opposed to at the bottom?

Sounds good to me. We can always adjust based on feedback.

Was this page helpful?
0 / 5 - 0 ratings