public static bool TryDetectWrapperType( this ITypeSymbol type, out DpdtArgumentWrapperTypeEnum wrapperType, [NotNullWhen(true)] out ITypeSymbol?internalType ) { if (type is null) { throw new ArgumentNullException(nameof(type)); } var namedType = type as INamedTypeSymbol; if (namedType is null) { wrapperType = DpdtArgumentWrapperTypeEnum.None; internalType = null; return(false); } var extractedName = type.Name; if (extractedName == "Func") { wrapperType = DpdtArgumentWrapperTypeEnum.Func; internalType = namedType.TypeArguments[0]; return(true); } wrapperType = DpdtArgumentWrapperTypeEnum.None; internalType = null; return(false); }
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 string GetPostfix( this DpdtArgumentWrapperTypeEnum wrapperType ) { switch (wrapperType) { case DpdtArgumentWrapperTypeEnum.None: return(string.Empty); case DpdtArgumentWrapperTypeEnum.Func: return("_Func"); default: throw new ArgumentOutOfRangeException(wrapperType.ToString()); } }
private IMethodProduct CreateExplicitMethod( string explicitMethodName, IMethodProduct nonExplicitMethod, DpdtArgumentWrapperTypeEnum wrapperType, ITypeSymbol wrapperSymbol ) { var explicitMethodProduct = MethodProductFactory.Create( explicitMethodName, nonExplicitMethod.MethodResult, (methodName, returnType) => $@"{returnType} {GN.IResolution}<{wrapperSymbol.ToGlobalDisplayString()}>.{methodName}({GN.IResolutionRequest} resolutionRequest) {{ return {nonExplicitMethod.MethodName}(resolutionRequest); }} " ); return(explicitMethodProduct); }
private MethodProduct CreateExplicitMethod( string explicitMethodName, MethodProduct nonExplicitMethod, DpdtArgumentWrapperTypeEnum wrapperType, ITypeSymbol wrapperSymbol ) { var explicitMethodProduct = new MethodProduct( explicitMethodName, nonExplicitMethod.ReturnType, (methodName, returnType) => $@" {returnType.ToDisplayString()} IResolution<{wrapperSymbol.ToDisplayString()}>.{methodName}(IResolutionRequest resolutionRequest) {{ return {nonExplicitMethod.MethodName}(resolutionRequest); }} " ); return(explicitMethodProduct); }
public static ITypeSymbol GenerateWrapperTypes( this ITypeSymbol type, ITypeInfoProvider typeInfoProvider, DpdtArgumentWrapperTypeEnum wrapperType ) { ITypeSymbol wrapperSymbol; switch (wrapperType) { case DpdtArgumentWrapperTypeEnum.None: wrapperSymbol = type; break; case DpdtArgumentWrapperTypeEnum.Func: wrapperSymbol = typeInfoProvider.Func(type); break; default: throw new ArgumentOutOfRangeException(wrapperType.ToString()); } return(wrapperSymbol); }
private ResolutionProduct CreateResolutionProduct( IReadOnlyList <InstanceProduct> filteredInstanceProducts, DpdtArgumentWrapperTypeEnum wrapperType, ITypeSymbol wrapperSymbol ) { var interfaceProduct = new NamedGeneric1Interface( GN.IResolution, wrapperSymbol ); var interfaceFastProduct = new NamedGeneric1Interface( GN.IResolutionFast, wrapperSymbol ); #region get var getMethodProduct = CreateGetMethod( filteredInstanceProducts, wrapperType, wrapperSymbol ); var getExplicitMethodProduct = CreateExplicitMethod( "Get", getMethodProduct, wrapperType, wrapperSymbol ); var canBeImplicitelyCastedToObject = wrapperSymbol.IsReferenceType; var nonGenericGetProduct = new CreateTupleProduct( new TypeTypePair ( _typeInfoProvider.SystemType(), wrapperSymbol ), new TypeStringPair ( _typeInfoProvider.Func( _typeInfoProvider.GetTypeByMetadataName(typeof(IResolutionRequest).FullName !) !, _typeInfoProvider.Object() ! ), canBeImplicitelyCastedToObject ? getMethodProduct.MethodName : $"(r) => {getMethodProduct.MethodName}(r)" ) ); #endregion #region get all var getAllMethodProduct = CreateGetAllMethod( filteredInstanceProducts, wrapperType, wrapperSymbol ); var getAllExplicitMethodProduct = CreateExplicitMethod( "GetAll", getAllMethodProduct, wrapperType, wrapperSymbol ); var nonGenericGetAllProduct = new CreateTupleProduct( new TypeTypePair ( _typeInfoProvider.SystemType(), wrapperSymbol ), new TypeStringPair ( _typeInfoProvider.Func( _typeInfoProvider.GetTypeByMetadataName(typeof(IResolutionRequest).FullName !) !, _typeInfoProvider.Object() ! ), canBeImplicitelyCastedToObject ? getAllMethodProduct.MethodName : $"(r) => {getAllMethodProduct.MethodName}(r)" ) ); #endregion #region get fast var getFastMethodProduct = MethodProductFactory.Create( nameof(IResolutionFast <object> .GetFast), new TypeMethodResult(wrapperSymbol), (methodName, returnType) => { return($@" {GN.AggressiveInlining} public {returnType} {methodName}({returnType} unused) {{ return {getMethodProduct.MethodName}( null ); }} "); } ); #endregion var resolutionProduct = new ResolutionProduct( interfaceProduct, interfaceFastProduct, getMethodProduct, getExplicitMethodProduct, nonGenericGetProduct, getAllMethodProduct, getAllExplicitMethodProduct, nonGenericGetAllProduct, getFastMethodProduct ); return(resolutionProduct); }
public string GetWrappedMethodName(DpdtArgumentWrapperTypeEnum wrapperType) { return ($"{MethodName}{wrapperType.GetPostfix()}"); }
private ResolutionProduct CreateResolutionProduct( IReadOnlyList <InstanceProduct> filteredInstanceProducts, DpdtArgumentWrapperTypeEnum wrapperType, ITypeSymbol wrapperSymbol ) { var interfaceProduct = new InterfaceProduct( $"{nameof(IResolution<object>)}<{wrapperSymbol.ToDisplayString()}>" ); var interfaceFastProduct = new InterfaceProduct( $"{nameof(IResolutionFast<object>)}<{wrapperSymbol.ToDisplayString()}>" ); #region get var getMethodProduct = CreateGetMethod( filteredInstanceProducts, wrapperType, wrapperSymbol ); var getExplicitMethodProduct = CreateExplicitMethod( "Get", getMethodProduct, wrapperType, wrapperSymbol ); var nonGenericGetProduct = new CreateTupleProduct( ( _typeInfoProvider.SystemType(), $"typeof({wrapperSymbol.ToDisplayString()})" ), ( _typeInfoProvider.Func( _typeInfoProvider.GetTypeByMetadataName(typeof(IResolutionRequest).FullName !) !, _typeInfoProvider.Object() ! ), getMethodProduct.MethodName ) ); #endregion #region get all var getAllMethodProduct = CreateGetAllMethod( filteredInstanceProducts, wrapperType, wrapperSymbol ); var getAllExplicitMethodProduct = CreateExplicitMethod( "GetAll", getAllMethodProduct, wrapperType, wrapperSymbol ); var nonGenericGetAllProduct = new CreateTupleProduct( ( _typeInfoProvider.SystemType(), $"typeof({wrapperSymbol.ToDisplayString()})" ), ( _typeInfoProvider.Func( _typeInfoProvider.GetTypeByMetadataName(typeof(IResolutionRequest).FullName !) !, _typeInfoProvider.Object() ! ), getAllMethodProduct.MethodName ) ); #endregion #region get fast var getFastMethodProduct = new MethodProduct( nameof(IResolutionFast <object> .GetFast), wrapperSymbol, (methodName, returnType) => { return($@" [MethodImpl(MethodImplOptions.AggressiveInlining)] public {returnType.ToDisplayString()} {methodName}({returnType.ToDisplayString()} unused) {{ return {getMethodProduct.MethodName}( null ); }} "); } ); #endregion var resolutionProduct = new ResolutionProduct( interfaceProduct, interfaceFastProduct, getMethodProduct, getExplicitMethodProduct, nonGenericGetProduct, getAllMethodProduct, getAllExplicitMethodProduct, nonGenericGetAllProduct, getFastMethodProduct ); return(resolutionProduct); }