private IMethodProduct CreateGetAllMethod( IReadOnlyList <InstanceProduct> filteredInstanceProducts, DpdtArgumentWrapperTypeEnum wrapperType, ITypeSymbol wrapperSymbol ) { var stableSuffix = GetStableSuffix(filteredInstanceProducts); string nonExplicitMethodName = $"GetAll_{wrapperSymbol.GetSpecialName()}_{stableSuffix}" ; var returnType = _typeInfoProvider .GetTypeByMetadataName("System.Collections.Generic.List`1") ! .Construct(wrapperSymbol) ; var getAllMethodProduct = MethodProductFactory.Create( nonExplicitMethodName, new TypeMethodResult(returnType), (methodName, returnType) => { var methodBody = $@"private {returnType} {methodName}({GN.IResolutionRequest} resolutionRequest) {{ resolutionRequest = resolutionRequest ?? new {GN.ResolutionRequest}<{ClusterBindings.ClusterType.ToGlobalDisplayString()}, {wrapperSymbol.ToGlobalDisplayString()}>(true); var result = new global::System.Collections.Generic.List<{wrapperSymbol.ToGlobalDisplayString()}>(); "; foreach (var instanceProduct in filteredInstanceProducts) { var modifiedContext = $"target_{instanceProduct.BindingExtender.BindingContainer.GetStableSuffix()}"; if (!(instanceProduct.PredicateMethod is null) || instanceProduct.BindingExtender.NeedToProcessResolutionContext) { methodBody += $@" var {modifiedContext} = new {GN.ResolutionTarget}<{ClusterBindings.ClusterType.ToGlobalDisplayString()}, {instanceProduct.BindingExtender.BindingContainer.BindToType.ToGlobalDisplayString()}>( resolutionRequest ); "; } if (!(instanceProduct.PredicateMethod is null)) { //with predicate (itself is conditional!) methodBody += $@"//predicate method is same for all wrappers, so we does no need for a wrapper-postfix (like _Func) if({instanceProduct.PredicateMethod.GetWrappedMethodName(DpdtArgumentWrapperTypeEnum.None)}({modifiedContext})) {{ result.Add( {instanceProduct.FactoryObjectMethod.GetWrappedMethodName(wrapperType)}({modifiedContext}) ); }} "; }
public static INamedTypeSymbol Void( this ITypeInfoProvider typeInfoProvider ) { if (typeInfoProvider is null) { throw new ArgumentNullException(nameof(typeInfoProvider)); } return(typeInfoProvider.GetTypeByMetadataName("System.Void") !); }
public static INamedTypeSymbol Func( this ITypeInfoProvider typeInfoProvider, params ITypeSymbol[] genericParameters ) { if (typeInfoProvider is null) { throw new ArgumentNullException(nameof(typeInfoProvider)); } return (typeInfoProvider.GetTypeByMetadataName("System.Func`" + genericParameters.Length) ! .Construct(genericParameters) ); }
private void ProcessSingleton( ExpressionStatementSyntax expressionNode, GenericNameSyntax bindGenericNode, ArgumentSyntax?whenArgumentClause ) { var genericNodes = expressionNode .DescendantNodes() .OfType <GenericNameSyntax>() .ToList(); var toGenericNode = genericNodes[1]; var toMethodName = toGenericNode.Identifier.Text; if (toMethodName.NotIn(nameof(IToOrConstantBinding.To), nameof(IToOrConstantBinding.ToFactory))) { throw new DpdtException(DpdtExceptionTypeEnum.InternalError, "Cannot find To clause for singleton binding"); } var factoryPayloadSemantic = GetFactoryPayloadIfExists( toGenericNode ); var bindFromTypeSemantics = GetBindFromTypes( bindGenericNode ); var bindToSyntax = toGenericNode.TypeArgumentList.Arguments.First(); var bindToTypeSemantic = _semanticModel.GetTypeInfo(bindToSyntax).Type; if (bindToTypeSemantic == null) { throw new DpdtException( DpdtExceptionTypeEnum.InternalError, $"Unknown problem to access {nameof(bindToTypeSemantic)}" ); } CheckForFromAndToTypes( bindFromTypeSemantics, bindToTypeSemantic, !(factoryPayloadSemantic is null) ); var fullBindToTypeName = _typeInfoProvider.GetTypeByMetadataName(bindToTypeSemantic.ToDisplayString()); if (fullBindToTypeName == null) { throw new DpdtException( DpdtExceptionTypeEnum.InternalError, $"Unknown problem to access type for {bindToTypeSemantic.ToDisplayString()}" ); } var caExtractor = new ConstructorArgumentExtractor( _typeInfoProvider, _semanticModel ); caExtractor.Visit(expressionNode); var constructorArguments = GetConstructorArguments( caExtractor, fullBindToTypeName ); var bindingContainer = new BindingContainerWithInstance( bindFromTypeSemantics, bindToTypeSemantic, constructorArguments, BindScopeEnum.Singleton, whenArgumentClause, factoryPayloadSemantic ); _bindingContainers.Add(bindingContainer); }