public IEnumerable <SyntaxNode> GenerateImplementation(IMethodSymbol methodSymbol, SyntaxGenerator generator,
                                                               SemanticModel semanticModel, MappingContext mappingContext)
        {
            var mappingEngine = new MappingEngine(semanticModel, generator);
            var sourceFinder  = new LocalScopeMappingSourceFinder(semanticModel, methodSymbol.Parameters);
            var targets       = MappingTargetHelper.GetFieldsThaCanBeSetPrivately(methodSymbol.ContainingType, mappingContext);

            return(mappingEngine.MapUsingSimpleAssignment(targets, new SingleSourceMatcher(sourceFinder), mappingContext));
        }
예제 #2
0
        public IEnumerable <SyntaxNode> GenerateImplementation(IMethodSymbol methodSymbol, SyntaxGenerator generator,
                                                               SemanticModel semanticModel, MappingContext mappingContext)
        {
            var mappingEngine   = new MappingEngine(semanticModel, generator);
            var sourceParameter = methodSymbol.Parameters[0];
            var sourceFinder    = new ObjectMembersMappingSourceFinder(new AnnotatedType(sourceParameter.Type), generator.IdentifierName(sourceParameter.Name), generator);
            var targets         = MappingTargetHelper.GetFieldsThaCanBeSetFromConstructor(methodSymbol.ContainingType, mappingContext);

            return(mappingEngine.MapUsingSimpleAssignment(targets, new SingleSourceMatcher(sourceFinder), mappingContext));
        }
예제 #3
0
        public async Task <IReadOnlyList <SyntaxNode> > GenerateImplementation(IMethodSymbol methodSymbol, SyntaxGenerator generator,
                                                                               SemanticModel semanticModel, MappingContext mappingContext)
        {
            var mappingEngine       = new MappingEngine(semanticModel, generator);
            var sourceFinder        = new LocalScopeMappingSourceFinder(semanticModel, methodSymbol.Parameters);
            var mappingTargetHelper = new MappingTargetHelper();
            var targets             = mappingTargetHelper.GetFieldsThaCanBeSetFromConstructor(methodSymbol.ContainingType, mappingContext);

            return(await mappingEngine.MapUsingSimpleAssignment(targets, new SingleSourceMatcher(sourceFinder), mappingContext).ConfigureAwait(false));
        }
예제 #4
0
        public ObjectCreationExpressionSyntax AddInitializerWithMapping(
            ObjectCreationExpressionSyntax objectCreationExpression, IMappingMatcher mappingMatcher,
            ITypeSymbol createdObjectTyp,
            MappingContext mappingContext,
            MappingPath mappingPath = null)
        {
            var propertiesToSet = MappingTargetHelper.GetFieldsThaCanBeSetPublicly(createdObjectTyp, mappingContext);
            var assignments     = MapUsingSimpleAssignment(propertiesToSet, mappingMatcher, mappingContext, mappingPath).ToList();

            return(SyntaxFactoryExtensions.WithMembersInitialization(objectCreationExpression, assignments));
        }
예제 #5
0
        public IEnumerable <SyntaxNode> GenerateImplementation(IMethodSymbol methodSymbol, SyntaxGenerator generator,
                                                               SemanticModel semanticModel, MappingContext mappingContext)
        {
            var mappingEngine = new MappingEngine(semanticModel, generator);
            var source        = methodSymbol.Parameters[0];
            var target        = methodSymbol.Parameters[1];
            var targets       = MappingTargetHelper.GetFieldsThaCanBeSetPublicly(target.Type, mappingContext);
            var sourceFinder  = new ObjectMembersMappingSourceFinder(source.Type, generator.IdentifierName(source.Name), generator);

            return(mappingEngine.MapUsingSimpleAssignment(targets, new SingleSourceMatcher(sourceFinder), mappingContext, globalTargetAccessor: generator.IdentifierName(target.Name)));
        }
예제 #6
0
        public async Task <IReadOnlyList <SyntaxNode> > GenerateImplementation(IMethodSymbol methodSymbol, SyntaxGenerator generator,
                                                                               SemanticModel semanticModel, MappingContext mappingContext)
        {
            var mappingEngine       = new MappingEngine(semanticModel, generator);
            var source              = methodSymbol.Parameters[0];
            var sourceFinder        = new ObjectMembersMappingSourceFinder(new AnnotatedType(source.Type), generator.IdentifierName(source.Name));
            var mappingTargetHelper = new MappingTargetHelper();
            var targets             = mappingTargetHelper.GetFieldsThaCanBeSetPrivately(methodSymbol.ContainingType, mappingContext);

            return(await mappingEngine.MapUsingSimpleAssignment(targets, new SingleSourceMatcher(sourceFinder), mappingContext).ConfigureAwait(false));
        }
예제 #7
0
        private static async Task <Document> ReplaceWithMappingBody(Document document, LambdaExpressionSyntax lambda, SemanticModel semanticModel, IMappingMatcher mappingMatcher, CancellationToken cancellationToken)
        {
            var methodSymbol      = (IMethodSymbol)semanticModel.GetSymbolInfo(lambda).Symbol;
            var createdObjectType = methodSymbol.Parameters.First().Type;
            var mappingEngine     = await MappingEngine.Create(document, cancellationToken);

            var mappingContext  = new MappingContext(lambda, semanticModel);
            var propertiesToSet = MappingTargetHelper.GetFieldsThaCanBeSetPublicly(createdObjectType, mappingContext);
            var statements      = mappingEngine.MapUsingSimpleAssignment(propertiesToSet, mappingMatcher, mappingContext, globalTargetAccessor: SyntaxFactory.IdentifierName(GetParameterIdentifier(lambda)))
                                  .Select(x => x.AsStatement().WithTrailingTrivia(SyntaxFactory.EndOfLine("\r\n")));

            var newLambda = UpdateLambdaBody(lambda, SyntaxFactory.Block(statements)).WithAdditionalAnnotations(Formatter.Annotation);

            return(await document.ReplaceNodes(lambda, newLambda, cancellationToken));
        }
예제 #8
0
        public ObjectCreationExpressionSyntax AddInitializerWithMapping(
            ObjectCreationExpressionSyntax objectCreationExpression, IMappingMatcher mappingMatcher,
            ITypeSymbol createdObjectTyp,
            MappingContext mappingContext,
            MappingPath mappingPath = null)
        {
            var propertiesToSet = MappingTargetHelper.GetFieldsThaCanBeSetPublicly(createdObjectTyp, mappingContext);
            var assignments     = MapUsingSimpleAssignment(propertiesToSet, mappingMatcher, mappingContext, mappingPath).ToList();

            if (assignments.Count == 0)
            {
                return(objectCreationExpression);
            }
            var initializerExpressionSyntax = SyntaxFactory.InitializerExpression(SyntaxKind.ObjectInitializerExpression, new SeparatedSyntaxList <ExpressionSyntax>().AddRange(assignments)).FixInitializerExpressionFormatting(objectCreationExpression);

            return(objectCreationExpression.WithInitializer(initializerExpressionSyntax));
        }
예제 #9
0
        internal SyntaxNode GetDefaultExpression(ITypeSymbol type, MappingContext mappingContext, MappingPath mappingPath)
        {
            if (mappingPath.AddToMapped(type) == false)
            {
                return(syntaxGenerator.DefaultExpression(type)
                       .WithTrailingTrivia(SyntaxFactory.Comment(" /* Stop recursive mapping */")));
            }

            if (SymbolHelper.IsNullable(type, out var underlyingType))
            {
                type = underlyingType;
            }


            if (type.TypeKind == TypeKind.Enum && type is INamedTypeSymbol namedTypeSymbol)
            {
                var enumOptions = namedTypeSymbol.MemberNames.Where(x => x != "value__" && x != ".ctor").OrderBy(x => x).ToList();
                if (enumOptions.Count > 0)
                {
                    return(syntaxGenerator.MemberAccessExpression(syntaxGenerator.IdentifierName(namedTypeSymbol.Name), syntaxGenerator.IdentifierName(enumOptions[0])));
                }
                return(syntaxGenerator.DefaultExpression(type));
            }

            if (type.SpecialType == SpecialType.None)
            {
                var objectCreationExpression = (ObjectCreationExpressionSyntax)syntaxGenerator.ObjectCreationExpression(type);


                if (MappingHelper.IsCollection(type))
                {
                    var isReadonlyCollection = ObjectHelper.IsReadonlyCollection(type);

                    if (type is IArrayTypeSymbol)
                    {
                        objectCreationExpression = SyntaxFactory.ObjectCreationExpression((TypeSyntax)syntaxGenerator.TypeExpression(type));
                    }
                    else if (type.TypeKind == TypeKind.Interface || isReadonlyCollection)
                    {
                        var namedType = type as INamedTypeSymbol;
                        if (namedType.IsGenericType)
                        {
                            var typeArgumentListSyntax = SyntaxFactory.TypeArgumentList(SyntaxFactory.SeparatedList(namedType.TypeArguments.Select(x => syntaxGenerator.TypeExpression(x))));
                            var newType = SyntaxFactory.GenericName(SyntaxFactory.Identifier("List"), typeArgumentListSyntax);
                            objectCreationExpression = SyntaxFactory.ObjectCreationExpression(newType, SyntaxFactory.ArgumentList(), default(InitializerExpressionSyntax));
                        }
                        else
                        {
                            var newType = SyntaxFactory.ParseTypeName("ArrayList");
                            objectCreationExpression = SyntaxFactory.ObjectCreationExpression(newType, SyntaxFactory.ArgumentList(), default(InitializerExpressionSyntax));
                        }
                    }
                    var subType = MappingHelper.GetElementType(type);
                    var initializationBlockExpressions = new SeparatedSyntaxList <ExpressionSyntax>();
                    var subTypeDefault = (ExpressionSyntax)GetDefaultExpression(subType, mappingContext, mappingPath.Clone());
                    if (subTypeDefault != null)
                    {
                        initializationBlockExpressions = initializationBlockExpressions.Add(subTypeDefault);
                    }

                    var initializerExpressionSyntax = SyntaxFactory.InitializerExpression(SyntaxKind.ObjectInitializerExpression, initializationBlockExpressions).FixInitializerExpressionFormatting(objectCreationExpression);
                    return(objectCreationExpression
                           .WithInitializer(initializerExpressionSyntax)
                           .WrapInReadonlyCollectionIfNecessary(isReadonlyCollection, syntaxGenerator));
                }

                {
                    var nt = type as INamedTypeSymbol;

                    if (nt == null)
                    {
                        var genericTypeConstraints = type.UnwrapGeneric().ToList();
                        if (genericTypeConstraints.Any() == false)
                        {
                            return(GetDefaultForUnknown(type, SyntaxFactory.ParseTypeName("object")));
                        }
                        nt = genericTypeConstraints.FirstOrDefault(x => x.TypeKind == TypeKind.Class) as INamedTypeSymbol ??
                             genericTypeConstraints.FirstOrDefault(x => x.TypeKind == TypeKind.Interface) as INamedTypeSymbol;
                    }

                    if (nt == null)
                    {
                        return(GetDefaultForUnknownType(type));
                    }

                    if (nt.TypeKind == TypeKind.Interface)
                    {
                        var implementations     = SymbolFinder.FindImplementationsAsync(type, this._document.Project.Solution).Result;
                        var firstImplementation = implementations.FirstOrDefault();
                        if (firstImplementation is INamedTypeSymbol == false)
                        {
                            return(GetDefaultForUnknownType(type));
                        }

                        nt = firstImplementation as INamedTypeSymbol;
                        objectCreationExpression = (ObjectCreationExpressionSyntax)syntaxGenerator.ObjectCreationExpression(nt);
                    }
                    else if (nt.TypeKind == TypeKind.Class && nt.IsAbstract)
                    {
                        var randomDerived = SymbolFinder.FindDerivedClassesAsync(nt, this._document.Project.Solution).Result
                                            .FirstOrDefault(x => x.IsAbstract == false);

                        if (randomDerived != null)
                        {
                            nt = randomDerived;
                            objectCreationExpression = (ObjectCreationExpressionSyntax)syntaxGenerator.ObjectCreationExpression(nt);
                        }
                    }

                    var publicConstructors    = nt.Constructors.Where(x => mappingContext.AccessibilityHelper.IsSymbolAccessible(x, nt)).ToList();
                    var hasDefaultConstructor = publicConstructors.Any(x => x.Parameters.Length == 0);
                    if (hasDefaultConstructor == false && publicConstructors.Count > 0)
                    {
                        var randomConstructor    = publicConstructors.First();
                        var constructorArguments = randomConstructor.Parameters.Select(p => GetDefaultExpression(p.Type, mappingContext, mappingPath.Clone())).ToList();
                        objectCreationExpression = (ObjectCreationExpressionSyntax)syntaxGenerator.ObjectCreationExpression(nt, constructorArguments);
                    }

                    var fields      = MappingTargetHelper.GetFieldsThaCanBeSetPublicly(nt, mappingContext);
                    var assignments = fields.Select(x =>
                    {
                        var identifier = (ExpressionSyntax)(SyntaxFactory.IdentifierName(x.Name));
                        return((ExpressionSyntax)syntaxGenerator.AssignmentStatement(identifier, this.FindMappingSource(x.Type, mappingContext, mappingPath.Clone()).Expression));
                    }).ToList();

                    if (assignments.Count == 0)
                    {
                        return(objectCreationExpression);
                    }
                    var initializerExpressionSyntax = SyntaxFactory.InitializerExpression(SyntaxKind.ObjectInitializerExpression, new SeparatedSyntaxList <ExpressionSyntax>().AddRange(assignments)).FixInitializerExpressionFormatting(objectCreationExpression);
                    return(objectCreationExpression.WithInitializer(initializerExpressionSyntax));
                }
            }


            return(GetDefaultForSpecialType(type));
        }