private List <DetectedConstructorArgument> GetConstructorArguments( ConstructorArgumentExtractor extractor, INamedTypeSymbol fullBindToTypeName ) { if (extractor is null) { throw new ArgumentNullException(nameof(extractor)); } if (fullBindToTypeName is null) { throw new ArgumentNullException(nameof(fullBindToTypeName)); } var constructorArguments = extractor.GetConstructorArguments(); var chosenConstructor = ChooseConstructor( fullBindToTypeName, constructorArguments ); foreach (var cParameter in chosenConstructor.Parameters) { var cParameterName = cParameter.Name; var cParameterType = cParameter.Type; var found = constructorArguments.FirstOrDefault(ca => ca.Name == cParameterName); if (found is null) { constructorArguments.Add( new DetectedConstructorArgument( cParameterName, cParameterType, cParameter.HasExplicitDefaultValue ) ); } } return(constructorArguments); }
private void ProcessCustom( 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 custom 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.Custom, whenArgumentClause, factoryPayloadSemantic ); _bindingContainers.Add(bindingContainer); }