Ejemplo n.º 1
0
        private CodeNodeBuilder UseChainedMethods <TChainedMethod>(CodeNodeBuilder builder, TChainedMethod chainedMethod, List <MethodSignature> methods, Action <CodeNodeBuilder> node) where TChainedMethod : MemberChainedMethods <TChainedMethod>
        {
            builder.AttributeMethodImpl(MethodImplOptions.AggressiveInlining);
            builder.AddMethod(chainedMethod.MethodSignature, node);

            // Maybe we don't need to generate these methods when it's constant length
            for (var i = 0; i < _features.Count; ++i)
            {
                if (!chainedMethod.HasChainedMethodInvoked)
                {
                    return(builder);
                }
                var shouldMoveNext = i == _features.Count - 1; // Check if it's the last feature available
                chainedMethod = chainedMethod.MoveNext(shouldMoveNext);

                builder.AttributeMethodImpl(MethodImplOptions.AggressiveInlining);
                builder.AddMethod(chainedMethod.MethodSignature, node => _features[i].SerializeWriter(node, chainedMethod));
            }

            methods.Add(chainedMethod.MethodSignature);
            return(builder);
        }
        private void AddFeaturingMethods(CodeNodeBuilder builder)
        {
            if (_features.Count == 0)
            {
                throw new InvalidOperationException("Feature count cannot be zero!");
            }

            foreach (var method in _info.ChainingMethods)
            {
                var methodBodies = GetMethodBodies(method);
                for (var i = 0; i < methodBodies.Count; ++i)
                {
                    var currentMethod = method;
                    if (i != 0)
                    {
                        currentMethod = method.Rename(Accessibility.Private, GetNextMethodName(method, i));
                    }
                    builder.AddMethod(currentMethod, node => node.AddPlain(methodBodies[i]));
                }
            }

            IReadOnlyList <string> GetMethodBodies(MethodSignature method)
            {
                var list = new List <string>(_features.Count);

                for (var i = 0; i < _features.Count; i++)
                {
                    var feature        = _features[i];
                    var isLast         = i == _features.Count - 1;
                    var methodProvider = new ChainingMethodProvider(method.Arguments, isLast ? null : GetNextMethodName(method, i));
                    // We need to evaluate it first
                    list.Add(feature.GetMethodBody(method.MethodName, methodProvider));
                    if (!methodProvider.HasInvokedNextMethod)
                    {
                        break;
                    }
                }
                return(list);
            }