Exemple #1
0
 private static void WriteLocations(LamarWiringCtx item)
 {
     Console.WriteLine($"\t\t{item.Invocation.GetLocation()}");
 }
Exemple #2
0
            private void AnalyzeInvocation(SyntaxNodeAnalysisContext context, InvocationExpressionSyntax node, IMethodSymbol method)
            {
                var invocationNodes = node.Parent.Ancestors().OfType <InvocationExpressionSyntax>().ToArray();

                var invocations = (from i in invocationNodes
                                   let sym = context.SemanticModel.GetSymbolInfo(i)
                                             where sym.Symbol?.Kind == SymbolKind.Method
                                             let methodSymbol = (IMethodSymbol)sym.Symbol
                                                                select new StructureMapConfigurationInvocation(methodSymbol, i)).ToArray();

                ITypeSymbol    plugin;
                LamarLifecycle lifecycle = null;

                if (method.Name.Equals("ForSingletonOf"))
                {
                    lifecycle = LamarLifecycle.Singleton;
                }

                var assignment = node.Ancestors().OfType <AssignmentExpressionSyntax>().FirstOrDefault();

                ISymbol assignedTo = null;

                if (assignment != null)
                {
                    assignedTo = context.SemanticModel.GetSymbolInfo(assignment.Left).Symbol;
                }

                var variableDeclaration = node.Ancestors().OfType <VariableDeclarationSyntax>().FirstOrDefault();

                if (variableDeclaration != null)
                {
                    assignedTo = context.SemanticModel.GetDeclaredSymbol(variableDeclaration.Variables[0]);
                }

                ITypeSymbol PluginFromArgument(ExpressionSyntax expr)
                {
                    // ReSharper disable once ConvertIfStatementToSwitchStatement
                    if (expr is TypeOfExpressionSyntax toe)
                    {
                        var typeInfo = context.SemanticModel.GetTypeInfo(toe.Type);
                        return(typeInfo.Type);
                    }

                    // ReSharper disable once InvertIf
                    if (expr is InvocationExpressionSyntax ies && ies.Expression is MemberAccessExpressionSyntax mes)
                    {
                        var sym = context.SemanticModel.GetSymbolInfo(ies);
                        // ReSharper disable once InvertIf
                        if (sym.Symbol != null && sym.Symbol.Name.Equals("GetType"))
                        {
                            var typeInfo = context.SemanticModel.GetTypeInfo(mes.Expression);
                            return(typeInfo.Type);
                        }
                    }

                    if (expr is IdentifierNameSyntax ins)
                    {
                        var sym = context.SemanticModel.GetTypeInfo(ins);
                        return(sym.Type);
                    }

                    return(null);
                }

                LamarLifecycle LifecycleFromArgument(ExpressionSyntax expr)
                {
                    var lifecycleType = context.SemanticModel.GetTypeInfo(expr).Type;

                    return(LifecycleMap[lifecycleType.ToDisplayString()]);
                }

                if (method.IsGenericMethod)
                {
                    plugin = method.TypeArguments[0];

                    if (node.ArgumentList.Arguments.Count > 0)
                    {
                        lifecycle = LifecycleFromArgument(node.ArgumentList.Arguments[0].Expression);
                    }
                }
                else
                {
                    var expr = node.ArgumentList.Arguments[0].Expression;

                    plugin = PluginFromArgument(expr);
                }

                if (plugin == null)
                {
                    return;
                }

                LamarLifecycle FromInvocation(StructureMapConfigurationInvocation i)
                {
                    switch (i.MethodSymbol.Name)
                    {
                    case "Singleton":
                    {
                        return(LamarLifecycle.Singleton);
                    }

                    case "Scoped":
                    {
                        return(LamarLifecycle.Scoped);
                    }

                    case "Transient":
                    {
                        return(LamarLifecycle.Transient);
                    }

                    default:
                    {
                        return(null);
                    }
                    }
                }

                lifecycle = lifecycle ?? invocations.Select(FromInvocation).FirstOrDefault(x => x != null) ?? LamarLifecycle.TransientImplicit;

                var concretesPluggedBy = new[] { "Use", "Add" };

                var concretePluginInvocation =
                    invocations.FirstOrDefault(x => concretesPluggedBy.Any(s => s.Equals(x.MethodSymbol.Name, StringComparison.Ordinal)));

                var concretePlugin = plugin;

                ITypeSymbol ConcretePluginFrom(StructureMapConfigurationInvocation invocation)
                {
                    if (invocation.MethodSymbol.IsGenericMethod)
                    {
                        return(invocation.MethodSymbol.TypeArguments[0]);
                    }

                    var expr           = invocation.Invocation.ArgumentList.Arguments[invocation.Invocation.ArgumentList.Arguments.Count - 1].Expression;
                    var pluginToReturn = PluginFromArgument(expr);

                    if (pluginToReturn == null)
                    {
                        if (expr is LambdaExpressionSyntax les)
                        {
                            var bodyType = context.SemanticModel.GetTypeInfo(les.Body);
                            return(bodyType.Type ?? (context.SemanticModel.GetSymbolInfo(expr).Symbol as IMethodSymbol)?.ReturnType);
                        }
                    }

                    return(pluginToReturn);
                }

                if (concretePluginInvocation != null)
                {
                    concretePlugin = ConcretePluginFrom(concretePluginInvocation);
                }

                var assembly = context.Compilation.Assembly;

                var wiringCtx = new LamarWiringCtx(node, plugin, lifecycle, assembly, concretePlugin, assignedTo);

                host.wirings.Add(wiringCtx);
            }