Coder Social home page Coder Social logo

roslyn-analyzers's Introduction

Build status

roslyn-analyzers

Collection of useful Roslyn analyzers and code fixes.

AssignAll

Diagnostic error if there are unassigned members in an object initializer and a code fix to add the missing ones.

This is particularly useful when mapping between types, such as DTO types and database entity types. It ensures you don't forget to update the mapping when a new property is added or refactored.

I previously used AutoMapper to help with that, but now I can finally go back to good old object initializers that in my experience are easier to set up and as performant as can be.

Installation

  1. Install nuget AssignAll
  2. Add comment // AssignAll enable somewhere above the object initializers you want to analyze

Sample

private static void UnassignedMembersGiveBuildError()
{
    // AssignAll enable
    var foo = new Foo
    {
        // UnassignedProp and UnassignedField not assigned, diagnostic error lists both
        AssignedProp = true
    };
}

private class Foo
{
    public bool AssignedProp { get; set; }
    public int UnassignedProp { get; set; }
    public int UnassignedField;
}

Red squigglies on unassigned members in object initializer

Error list describes what properties or fields are not assigned.

Enable/disable by comments

Analysis must be explicitly enabled by a special comment, and can be disabled and re-enabled to only apply analysis to certain blocks of code. These comments can occur anywhere in the file and affects all the code below it, or until the next special comment.

// AssignAll enable
Foo foo = new Foo
{
    // PropInt not assigned, diagnostic error

    // AssignAll disable
    Bar = new Bar
    {
        // PropInt not assigned, but analyzer is disabled, no diagnostic error

        // AssignAll enable
        Baz = new Baz
        {
            // PropInt not assigned, analysis re-enabled, diagnostic error
        }
    }
};

Ignore properties and fields

Simply comment out the member assignments you want to ignore. This is particularly convenient when using the codefix to first generate all member assignments, then commenting out the ones you want to skip.

// AssignAll enable
var foo = new Foo
{
    // Ignore these assignments by commenting them out, it is whitespace tolerant
    // PropIgnored1 = ,
    //PropIgnored2=2,

    // PropUnassigned is unassigned and not commented out, diagnostic error
    PropAssigned = 1
};

private class Foo
{
    public int PropIgnored1 { get; set; }
    public int PropIgnored2 { get; set; }
    public int PropAssigned { get; set; }
    public int PropUnassigned { get; set; }
}

Code fix: Assign all members

Quickly populate all missing property assignments with an empty value so it does not compile until you assign all the values. This saves a lot of typing and intellisense browsing.

Apply code fix 'Assign all members'

Future improvements

  • Similar diagnostic for constructors (Constructor_AssignAll)
  • Auto-fill mapping members with identical or similar names
  • Code fix to ignore remaining missing members
  • Attributes to enable analysis for certain types
  • Attributes to ignore properties/fields
  • Configuration to enable/disable by default

roslyn-analyzers's People

Contributors

angularsen avatar anserg256 avatar liammorrow avatar pankraty avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar

roslyn-analyzers's Issues

Incorrect version of Microsoft.CodeAnalysis.CSharp.Workspaces

There is a warning generated when using AssignAll v.1.6.0:

[NU1603] AssignAll 1.6.0 depends on Microsoft.CodeAnalysis.CSharp.Workspaces (>= 3.3.3) but Microsoft.CodeAnalysis.CSharp.Workspaces 3.3.3 was not found. An approximate best match of Microsoft.CodeAnalysis.CSharp.Workspaces 3.4.0 was resolved.

(see https://ci.appveyor.com/project/angularsen/roslyn-analyzers/builds/44944678#L143)

Indeed, the mentioned library does not have such version: https://www.nuget.org/packages/Microsoft.CodeAnalysis.CSharp.Workspaces/#versions-body-tab

It seems, the version first was upgraded from 3.4.0 to 4.3.1 at this commit 907bd55, and then mistakingly reversed to 3.3.3 at this one 55a45de.

[AssignAll] attribute on method for aspect oriented programming

Magic comments like // AssignAll enable is a bit off-putting.

It would be more natural and discoverable with:

[AssignAll]
public PersonDto ToDto(Person entity)
{
	return new PersonDto
	{
		FullName = $"{entity.FirstName} {entity.LastName}"
	};
}

Instead of:

public PersonDto ToDto(Person entity)
{
    // AssignAll enable
	return new PersonDto
	{
		FullName = $"{entity.FirstName} {entity.LastName}"
	};
    // AssignAll disable
}

Analyze unit test asserts

Relates to #2 .

It would be helpful to get a compile error if a particular property is not accessed in an assert section of a unit test. This helps keep tests up to date when new properties are added.

Syntax proposal

Use // AccessAll {identifier list} to list all variables that should have their properties read or written.
Use :read or :write to specify type of access. Defaults to any of them.

// AccessAll slot:read
// The above comment will enable analyzer for the 'slot' variable and its properties.
// If any of its properties are not read, a compile error is generated.
slot.Price.Should().NotBeNull();
slot.Duration.Should().Be(TimeSpan.FromHours(2));
slot.Price.Currency.Should().Be("NOK");
slot.Price.AppliedDiscounts.Should().BeEmpty();

Support c#9 new() target-typed syntax

This doesn't trigger the analyzer:

// AssignAll enable
Foo r = new()
{
    Id = ,
    AddedDate = ,
    ModifiedDate = 
};
// AssignAll disable

But this does:

// AssignAll enable
Foo r = new Foo
{
    Id = ,
    AddedDate = ,
    ModifiedDate = 
};
// AssignAll disable

Enable for types

It would be really nice to be able to enable this on a single type similar to this

// Object_assignall enable class
public class MySillyClass {
    public Guid Foo { get; set; }
    public string Bar { get; set; }
}

And then in all other places in the code where I am using this class I could get this analysis for just this class. I think this would be a super-useful feature (although I admit that I have zero experience in roslyn analyzers and maybe doing this is really hard).

Analyzer ignores Inheritance

I tested the analyzer and realized that it does ignore inheritance. Given the following Code

     public class Base
    {
        public int A { get; set; }
    }


    public class Child : Base
    {
        public int B { get; set; }
    }

    public class Programm {
        public static void Main()
        {
            //AssignAll enable
            var x = new Child
            {

            };
            var y = new Child
            {
                B = 2
            };
        }
    }

I would have expected that y also throws an error. But at the moment only x will complain about missing members.

Analyze called Methods

Hi, i wonder if it would be possible to add/adapt the analyzer to also check called Methods. For Example:

abstract class MapperBase<TSource, TTarget>
    {
        //AssignAllDeep enable
        public abstract TTarget Map(TSource source);
        //AssignAllDeep disable
    }

So it would not be possible to forget to add the magic comment to the child classes.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.