cezarypiatek / MappingGenerator

:arrows_counterclockwise: "AutoMapper" like, Roslyn based, code fix provider that allows to generate mapping code in design time.
https://marketplace.visualstudio.com/items?itemName=54748ff9-45fc-43c2-8ec5-cf7912bc3b84.mappinggenerator
MIT License
1.03k stars 120 forks source link

Exception when clicking on tooltip - constructors #116

Closed surgicalcoder closed 4 years ago

surgicalcoder commented 4 years ago

Exception:

System.NullReferenceException : Object reference not set to an instance of an object.
   at MappingGenerator.MappingEngine.<>c__DisplayClass9_2.<TryToCreateMappingExpression>b__3(MappingElement x)
   at System.Linq.Enumerable.Any[TSource](IEnumerable`1 source,Func`2 predicate)
   at MappingGenerator.MappingEngine.<>c__DisplayClass9_1.<TryToCreateMappingExpression>b__2(MappingElement foundElement)
   at MappingGenerator.IgnorableMappingSourceFinder.FindMappingSource(String targetName,ITypeSymbol targetType)
   at MappingGenerator.MappingEngine.<>c__DisplayClass11_0.<MapUsingSimpleAssignment>b__0(IPropertySymbol property)
   at System.Linq.Enumerable.WhereSelectEnumerableIterator`2.MoveNext()
   at System.Linq.Enumerable.WhereSelectEnumerableIterator`2.MoveNext()
   at System.Collections.Generic.List`1..ctor(IEnumerable`1 collection)
   at System.Linq.Enumerable.ToList[TSource](IEnumerable`1 source)
   at MappingGenerator.MappingEngine.MapUsingSimpleAssignment(SyntaxGenerator generator,IEnumerable`1 targets,IMappingSourceFinder sourceFinder,MappingPath mappingPath,SyntaxNode globalTargetAccessor)
   at MappingGenerator.MappingEngine.AddInitializerWithMapping(ObjectCreationExpressionSyntax objectCreationExpression,IMappingSourceFinder mappingSourceFinder,ITypeSymbol createdObjectTyp,MappingPath mappingPath)
   at MappingGenerator.MappingEngine.TryToCreateMappingExpression(MappingElement source,ITypeSymbol targetType,MappingPath mappingPath)
   at MappingGenerator.MappingEngine.MapExpression(MappingElement element,ITypeSymbol targetType,MappingPath mappingPath)
   at MappingGenerator.MappingEngine.MapExpression(ExpressionSyntax sourceExpression,ITypeSymbol sourceType,ITypeSymbol destinationType)
   at MappingGenerator.MappingGeneratorRefactoring.GenerateMappingCode(IMethodSymbol methodSymbol,SyntaxGenerator generator,SemanticModel semanticModel)
   at async MappingGenerator.MappingGeneratorRefactoring.GenerateMappingMethodBody(<Unknown Parameters>)
   at async Microsoft.CodeAnalysis.CodeActions.CodeAction.GetChangedSolutionAsync(<Unknown Parameters>)
   at async Microsoft.CodeAnalysis.CodeActions.CodeAction.ComputeOperationsAsync(<Unknown Parameters>)
   at async Microsoft.CodeAnalysis.CodeActions.CodeAction.GetPreviewOperationsAsync(<Unknown Parameters>)
   at async Microsoft.CodeAnalysis.Editor.Implementation.Suggestions.SuggestedAction.GetPreviewResultAsync(<Unknown Parameters>)
   at async Microsoft.CodeAnalysis.Editor.Implementation.Suggestions.SuggestedActionWithNestedFlavors.PreviewChangesSuggestedAction.CreateAsync(<Unknown Parameters>)
   at async Microsoft.CodeAnalysis.Editor.Implementation.Suggestions.SuggestedActionWithNestedFlavors.GetPreviewChangesFlavor(<Unknown Parameters>)
   at async Microsoft.CodeAnalysis.Editor.Implementation.Suggestions.SuggestedActionWithNestedFlavors.CreateAllFlavors(<Unknown Parameters>)
   at async Microsoft.CodeAnalysis.Extensions.IExtensionManagerExtensions.PerformFunctionAsync[T](<Unknown Parameters>)

Method:

        public static UserLoginInfoEntity Convert(this UserLoginInfo info)
        {

        }

Source object is Microsoft.AspNetCore.Identity.UserLoginInfo

Destination object is:

public class UserLoginInfoEntity : Entity
    {
        public UserLoginInfoEntity() { }
        public UserLoginInfoEntity(string loginProvider, string providerKey, string providerDisplayName)
        {
            LoginProvider = loginProvider;
            ProviderKey = providerKey;
            ProviderDisplayName = providerDisplayName;
        }
        public string LoginProvider { get; set; }
        public string ProviderKey { get; set; }
        public string ProviderDisplayName { get; set; }
    }

If I comment out the constructors, it generates without an issue.

cezarypiatek commented 4 years ago

Sorry for the late response, I've been offline for a while. Can you provide the definition of UserLoginInfo and Entity as well?

surgicalcoder commented 4 years ago

Sure, UserLoginInfo is from Microsoft.AspNetCore.Identity:

public class UserLoginInfo
{
    public UserLoginInfo(string loginProvider, string providerKey, string displayName)
    {
        LoginProvider = loginProvider;
        ProviderKey = providerKey;
        ProviderDisplayName = displayName;
    }

    public string LoginProvider { get; set; }
    public string ProviderKey { get; set; }
    public string ProviderDisplayName { get; set; }
}

and Entity is:

  public abstract class Entity : IEquatable<Entity>
  {
    public virtual string Id { get; set; }

    public virtual long? Version { get; set; }

    public bool Equals(Entity other)
    {
      return other != null && this.Id == other.Id;
    }
  }
cezarypiatek commented 4 years ago

Unfortunately, I wasn't able to reproduce this issue. After running MappingGenerator action on your code I'm getting the following output:

public static UserLoginInfoEntity Convert(this UserLoginInfo info)
{
    return new UserLoginInfoEntity(loginProvider: info.LoginProvider, providerKey: info.ProviderKey, providerDisplayName: info.ProviderDisplayName);
}

What version of VisualStudio and MappingGenerator are you using? Can you provide a sample project which reproduces this issue?