Exemplo n.º 1
0
        public InstanceProduct Produce()
        {
            IMethodProduct?predicateMethod = null;

            if (_bindingExtender.BindingContainer.IsConditional)
            {
                predicateMethod = MethodProductFactory.Create(
                    $"CheckPredicate_{_bindingExtender.BindingContainer.BindToType.Name}_{_bindingExtender.BindingContainer.GetStableSuffix()}",
                    new TypeMethodResult(_typeInfoProvider.Bool()),
                    (methodName, returnType) => $@"
{GN.AggressiveInlining}
private {returnType} {methodName}({GN.IResolutionTarget} resolutionTarget)
{{
    global::System.Func<{GN.IResolutionTarget}, bool> predicate = 
        {_bindingExtender.BindingContainer.WhenArgumentClause}
        ;

    var result = predicate(resolutionTarget);
    return result;
}}
");
            }

            var retrieveObjectMethod = MethodProductFactory.Create(
                $"GetInstance_{_bindingExtender.BindingContainer.BindToType.Name}_{_bindingExtender.BindingContainer.GetStableSuffix()}",
                new TypeMethodResult(_bindingExtender.BindingContainer.BindToType),
                (methodName, returnType) => $@"
{GN.AggressiveInlining}
private {returnType} {methodName}(
    {GN.IResolutionTarget} resolutionTarget
    )
{{
    return {_bindingExtender.BindingContainer.ConstantSyntax!.GetText()};
}}
");

            var funcMethod = MethodProductFactory.Create(
                $"GetInstance_{_bindingExtender.BindingContainer.BindToType.Name}_{_bindingExtender.BindingContainer.GetStableSuffix()}{DpdtArgumentWrapperTypeEnum.Func.GetPostfix()}",
                new TypeMethodResult(_typeInfoProvider.Func(_bindingExtender.BindingContainer.BindToType)),
                (methodName, returnType) => $@"
{GN.AggressiveInlining}
private {returnType} {methodName}(
    {GN.IResolutionTarget} resolutionTarget
    )
{{
    return () => {retrieveObjectMethod.GetWrappedMethodName(DpdtArgumentWrapperTypeEnum.None)}(resolutionTarget);
}}
");

            var product = new InstanceProduct(
                _bindingExtender,
                predicateMethod,
                retrieveObjectMethod,
                funcMethod,
                null,
                null
                );

            return(product);
        }
        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})
            );
    }}
";
                    }
        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);
        }
Exemplo n.º 4
0
        public IMethodProduct GetMethodProduct(
            IMethodSymbol method
            )
        {
            if (method is null)
            {
                throw new ArgumentNullException(nameof(method));
            }

            var extractor            = new MethodArgumentExtractor();
            var constructorArguments = extractor.GetMethodArguments(method);


            var returnModifier = method.ReturnsVoid
                ? string.Empty
                : "return"
            ;

            var refModifier =
                (method.ReturnsByRef || method.ReturnsByRefReadonly)
                    ? "ref"
                    : string.Empty
            ;

            var result = MethodProductFactory.Create(
                method,
                constructorArguments,
                (methodName, h) =>
            {
                return($@"public {h}
        {{
            {returnModifier} {refModifier} _payload.{methodName}({constructorArguments.Join(ca => ca.GetUsageSyntax(), ",")});
        }}
");
            }
                );

            return(result);
        }
        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);
        }
Exemplo n.º 6
0
        public InstanceProduct Produce()
        {
            var constructorArgumentProducers = _bindingExtender.BindingContainer.ConstructorArguments.ConvertToProducers(
                _clusterBindings,
                _bindingExtender
                );

            var(caps, utps) = constructorArgumentProducers.Produce();

            IMethodProduct?predicateMethod = null;

            if (_bindingExtender.BindingContainer.IsConditional)
            {
                predicateMethod = MethodProductFactory.Create(
                    $"CheckPredicate_{_bindingExtender.BindingContainer.BindToType.Name}_{_bindingExtender.BindingContainer.GetStableSuffix()}",
                    new TypeMethodResult(_typeInfoProvider.Bool()),
                    (methodName, returnType) => $@"
{GN.AggressiveInlining}
private {returnType} {methodName}({GN.IResolutionTarget} resolutionTarget)
{{
    global::System.Func<{GN.IResolutionTarget}, bool> predicate = 
        {_bindingExtender.BindingContainer.WhenArgumentClause}
        ;

    var result = predicate(resolutionTarget);
    return result;
}}
");
            }

            var retrieveObjectMethod = MethodProductFactory.Create(
                $"GetInstance_{_bindingExtender.BindingContainer.BindToType.Name}_{_bindingExtender.BindingContainer.GetStableSuffix()}",
                new TypeMethodResult(_bindingExtender.BindingContainer.BindToType),
                (methodName, returnType) => $@"
{GN.AggressiveInlining}
private {returnType} {methodName}(
    {GN.IResolutionTarget} resolutionTarget
    )
{{
    return new {_bindingExtender.BindingContainer.BindToType.ToGlobalDisplayString()}(
        {caps.Join(p => p.ResolveConstructorArgumentClause, ",")}
        );
}}
");

            var funcMethod = MethodProductFactory.Create(
                $"GetInstance_{_bindingExtender.BindingContainer.BindToType.Name}_{_bindingExtender.BindingContainer.GetStableSuffix()}{DpdtArgumentWrapperTypeEnum.Func.GetPostfix()}",
                new TypeMethodResult(_typeInfoProvider.Func(_bindingExtender.BindingContainer.BindToType)),
                (methodName, returnType) => $@"
{GN.AggressiveInlining}
private {returnType} {methodName}(
    {GN.IResolutionTarget} resolutionTarget
    )
{{
    return () => {retrieveObjectMethod.GetWrappedMethodName(DpdtArgumentWrapperTypeEnum.None)}(resolutionTarget);
}}
");

            var product = new InstanceProduct(
                _bindingExtender,
                predicateMethod,
                retrieveObjectMethod,
                funcMethod,
                null,
                utps
                );

            return(product);
        }
Exemplo n.º 7
0
        public InstanceProduct Produce()
        {
            var constructorArgumentProducers = _bindingExtender.BindingContainer.ConstructorArguments.ConvertToProducers(
                _clusterBindings,
                _bindingExtender
                );

            var(caps, utps) = constructorArgumentProducers.Produce();

            IMethodProduct?predicateMethod = null;

            if (_bindingExtender.BindingContainer.IsConditional)
            {
                predicateMethod = MethodProductFactory.Create(
                    $"CheckPredicate_{_bindingExtender.BindingContainer.BindToType.Name}_{_bindingExtender.BindingContainer.GetStableSuffix()}",
                    new TypeMethodResult(_typeInfoProvider.Bool()),
                    (methodName, returnType) => $@"
{GN.AggressiveInlining}
private {returnType} {methodName}({GN.IResolutionTarget} resolutionTarget)
{{
    global::System.Func<{GN.IResolutionTarget}, bool> predicate = 
        {_bindingExtender.BindingContainer.WhenArgumentClause}
        ;

    var result = predicate(resolutionTarget);
    return result;
}}
");
            }

            var singletonInstanceName = $"_singletonInstance__{_bindingExtender.BindingContainer.BindToType.Name}__{_bindingExtender.BindingContainer.GetStableSuffix()}";
            var lockerName            = $"_locker_{_bindingExtender.BindingContainer.BindToType.Name}_{_bindingExtender.BindingContainer.GetStableSuffix()}";

            var retrieveObjectMethod = MethodProductFactory.Create(
                $"GetInstance_{_bindingExtender.BindingContainer.BindToType.Name}_{_bindingExtender.BindingContainer.GetStableSuffix()}",
                new TypeMethodResult(_bindingExtender.BindingContainer.BindToType),
                (methodName, returnType) => $@"
private volatile {_bindingExtender.BindingContainer.BindToType.ToGlobalDisplayString()} {singletonInstanceName} = null;
private readonly global::System.Object {lockerName} = new global::System.Object();

{GN.AggressiveInlining}
private {returnType} {methodName}(
    {GN.IResolutionTarget} resolutionTarget
    )
{{
    if({singletonInstanceName} is null)
    {{
        lock({lockerName})
        {{
            if({singletonInstanceName} is null)
            {{
                {singletonInstanceName} = new {_bindingExtender.BindingContainer.BindToType.ToGlobalDisplayString()}(
                    {caps.Join(p => p.ResolveConstructorArgumentClause, ",")}
                    );
            }}
        }}
    }}

    return {singletonInstanceName};
}}
");

            var funcMethod = MethodProductFactory.Create(
                $"GetInstance_{ _bindingExtender.BindingContainer.BindToType.Name}_{_bindingExtender.BindingContainer.GetStableSuffix()}{DpdtArgumentWrapperTypeEnum.Func.GetPostfix()}",
                new TypeMethodResult(_typeInfoProvider.Func(_bindingExtender.BindingContainer.BindToType)),
                (methodName, returnType) => $@"
{GN.AggressiveInlining}
private {returnType} {methodName}(
    {GN.IResolutionTarget} resolutionTarget
    )
{{
    return () => {retrieveObjectMethod.GetWrappedMethodName(DpdtArgumentWrapperTypeEnum.None)}(resolutionTarget);
}}
");

            var disposeMethodInvoke = MethodProductFactory.Create(
                $"DisposeInstance_{_bindingExtender.BindingContainer.BindToType.Name}_{_bindingExtender.BindingContainer.GetStableSuffix()}",
                new TypeMethodResult(_typeInfoProvider.Void()),
                (methodName, returnType) => $@"
private {returnType} {methodName}(
    )
{{
    if({singletonInstanceName} is {GN.IDisposable} d)
    {{
        d.{nameof(IDisposable.Dispose)}();
    }}
}}
");

            var product = new InstanceProduct(
                _bindingExtender,
                predicateMethod,
                retrieveObjectMethod,
                funcMethod,
                disposeMethodInvoke,
                utps
                );

            return(product);
        }