private CodeNodeBuilder AddTryConstructor(CodeNodeBuilder builder, INamedTypeSymbol discoveryType, IReadOnlyList <IComponentTypeInfo> components)
        {
            // Arguments
            const string parser    = "parser";
            const string isSuccess = "isSuccess";

            // Create Constructor with try pattern
            builder.AddNode($"public {_typeName.TypeName}({discoveryType} {parser}, out bool {isSuccess}) : this()", node => {
                for (var i = 0; i < components.Count; ++i)
                {
                    // Initialize every component
                    node.State($"{Field.Component(i)} = {MemberMethod.InitializeComponent(i)} ( {parser}, out {isSuccess} )");

                    // If any fails, we bail out
                    node.If($"!{isSuccess}", node => {
                        node.State($"{isSuccess} = false");
                        node.Return();
                    });
                }

                // Finally we state that we success
                node.State($"{isSuccess} = true");
            });

            return(builder);
        }
Ejemplo n.º 2
0
 private CodeNodeBuilder AddComponents(CodeNodeBuilder builder, IReadOnlyList <IComponentTypeInfo> components)
 {
     for (var i = 0; i < components.Count; ++i)
     {
         builder.State($"private {components[i].Type} {Field.Component(i)}");
     }
     return(builder);
 }
        private string MethodBase(TypeSourceArgs source, string nextMethodInvoke)
        {
            var node = new CodeNodeBuilder();

            node.If($"{(_isInverted ? "!" : "")}({_condition.GetEvalString(source.ToString(), Type, _expression)})", node => {
                node.Return(nextMethodInvoke);
            });
            node.Return(DeserializeResult.Success.ToDisplayString());

            return(node.ToString());
        }
Ejemplo n.º 4
0
        public CodeNodeBuilder Build(CodeNodeBuilder builder)
        {
            const string ReadOnlySpanByte = "ReadOnlySpan<byte>";
            const string SpanByte         = "Span<byte>";
            const string SequenceCursor   = "SequenceCursor<byte>";

            const string span         = "span";
            const string cursor       = "cursor";
            const string readBytes    = "readBytes";
            const string writtenBytes = "writtenBytes";
            const string target       = "target";

            var accessMod = _accessibility.ToString().ToLower();

            var strBuilder = new StringBuilder();

            foreach (var arg in PrependArguments)
            {
                strBuilder.Append(arg);
                strBuilder.Append(", ");
            }
            var prependString = strBuilder.ToString();

            // TryDeserialize (ReadOnlySpan<byte>)
            builder.AddNode($"{accessMod} {nameof(DeserializeResult)} {MethodNames.TryDeserializeSpan}({prependString}{ReadOnlySpanByte} {span}, out int {readBytes}, out {TargetSymbol} {target})",
                            node => TryDeserializeSpan(node, span, readBytes, target));

            // TryDeserialize (Sequence)
            builder.AddNode($"{accessMod} {nameof(DeserializeResult)} {MethodNames.TryDeserializeSequence}({prependString}{SequenceCursor} {cursor}, out {TargetSymbol} {target})",
                            node => TryDeserializeSequence(node, cursor, target));

            // Deserialize (ReadOnlySpan<byte>)
            builder.AddNode($"{accessMod} {TargetSymbol} {MethodNames.DeserializeSpan}({prependString}{ReadOnlySpanByte} {span}, out int {readBytes})",
                            node => DeserializeSpan(node, span, readBytes));

            // Deserialize (Sequence)
            builder.AddNode($"{accessMod} int {MethodNames.DeserializeSequence}({prependString}{SequenceCursor} {cursor})",
                            node => DeserializeSequence(node, cursor));


            // TrySerialize (ReadOnlySpan<byte>)
            builder.AddNode($"{accessMod} bool {MethodNames.TrySerialize}({prependString}in {TargetSymbol} {target}, {SpanByte} {span}, out int {writtenBytes})",
                            node => TrySerialize(node, target, span, writtenBytes));

            // Serialize (ReadOnlySpan<byte>)
            builder.AddNode($"{accessMod} int {MethodNames.Serialize}({prependString}in {TargetSymbol} {target}, {SpanByte} {span})",
                            node => Serialize(node, target, span));

            // GetLength
            builder.AddNode($"{accessMod} int {MethodNames.GetLength}({prependString}in {TargetSymbol} {target})",
                            node => GetLength(node, target));

            return(builder);
        }
        private CodeNodeBuilder AddConstructor(CodeNodeBuilder builder, INamedTypeSymbol discoveryType, IReadOnlyList <IComponentTypeInfo> components)
        {
            // Create Constructor
            const string parser = "parser";

            return(builder.AddNode($"public {_typeName.TypeName}({discoveryType} {parser}) : this()", node => {
                for (var i = 0; i < components.Count; ++i)
                {
                    node.State($"{Field.Component(i)} = {MemberMethod.InitializeComponent(i)} ( {parser} )");
                }
            }));
        }
        public string GetMethodBody(string methodId, IChainMethodArgsProvider provider, IComponentProvider components, IThrowCollection throwCollection)
        {
            var node = new CodeNodeBuilder();

            node.If($"{IsInvert()}({GetConditionString(provider)})", node => {
                node.Return(provider.InvokeNextMethod());
            });
            node.Return(DeserializeResult.Success.ToDisplayString());

            return(node.ToString());

            string IsInvert() => _isInverted ? "!" : "";
        }
Ejemplo n.º 7
0
        /// <returns>Next state arg name</returns>
        private string LoadNextWriteState <TChainedMethod>(CodeNodeBuilder node, TChainedMethod chainedMethod) where TChainedMethod : MemberChainedMethods <TChainedMethod>
        {
            const string nextState = "nextState";

            var tstateTypeName = TypeName.FromGenericArgument(SerializeWriterChainedMethods.T_STATE);
            var state          = chainedMethod[tstateTypeName];
            var tsource        = chainedMethod[TypeName.FromType(_member.ContainingFullType.Symbol)];

            node.If($"!{state}.Write({tsource}, out var {nextState})", node => {
                node.Return();
            });

            return(nextState);
        }
        private CodeNodeBuilder AddComponentInitializers(CodeNodeBuilder builder, INamedTypeSymbol discoveryType, IReadOnlyList <IComponentTypeInfo> components)
        {
            for (var i = 0; i < components.Count; ++i)
            {
                const string parserName = "parser";
                const string isSuccess  = "isSuccess";

                builder.AddNode($"private {components[i].Type} {MemberMethod.InitializeComponent(i)}({discoveryType} {parserName})", node => {
                    components[i].ProvideInitialize(node, parserName);
                });

                builder.AddNode($"private {components[i].Type} {MemberMethod.TryInitializeComponent(i)}({discoveryType} {parserName}, out bool {isSuccess})", node => {
                    components[i].ProvideTryInitialize(node, parserName, isSuccess);
                });
            }
            return(builder);
        }
Ejemplo n.º 9
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);
            }
        public void AddThrowClass(CodeNodeBuilder builder, Accessibility accessbility = Accessibility.Private, bool shouldShowInEditor = false)
        {
            var accessStr = accessbility.ToString().ToLower();

            if (!shouldShowInEditor)
            {
                builder.AttributeHideEditor();
            }
            builder.AddNode($"{accessStr} static class {_className} ", node => {
                for (var i = 0; i < exceptions.Count; i++)
                {
                    // Note to self : Don't add NoInlining to throw helpers, they actually make performance worse
                    // Maybe we can refer to these
                    // https://source.dot.net/#System.Memory/System/ThrowHelper.cs,73669ffe9b1ee4f4
                    // https://gist.github.com/benaadams/216ed9516dc4e67728fdef1a77574f96
                    var methodName = ThrowExceptionName(i);
                    node.State($"public static void {methodName}() => throw Create{methodName}").NewLine();
                    node.AttributeMethodImpl(MethodImplOptions.NoInlining);
                    node.State($"public static System.Exception Create{ThrowExceptionName(i)}() => {exceptions[i]}");
                }
            });
        }
 public override void GetLength(CodeNodeBuilder node, InArgs <object> target)
 => node.Return($"{MemberMethod.GetLengthState(0)}({parent}, {target} )");
 public override void DeserializeSequence(CodeNodeBuilder node, BufferArgs refSequenceCursor)
 => node.AddPlain($"{MemberMethod.TryDeserializeState(0)}({parent}, ref {refSequenceCursor})");
 public override void TrySerialize(CodeNodeBuilder node, InArgs <object> target, BufferArgs readOnlySpan, OutArgs <int> outWrittenBytes) => _body.TrySerialize(node, target, readOnlySpan, outWrittenBytes);
 public static CodeNodeBuilder AddParsingMethods(this CodeNodeBuilder builder, ParsingMethodBuilder group) => group.Build(builder);
Ejemplo n.º 16
0
 public abstract void Serialize(CodeNodeBuilder node, InArgs <object> target, BufferArgs readOnlySpan);
 public override void TryDeserializeSpan(CodeNodeBuilder node, BufferArgs readOnlySpan, OutArgs <int> outReadBytes, OutArgs <object> outResult)
 => node.Return($"{MemberMethod.TryDeserializeState(0)}({parent}, {readOnlySpan}, out {outReadBytes}, out {outResult})");
 public override void TryDeserializeSequence(CodeNodeBuilder node, BufferArgs refSequenceCursor, OutArgs <object> outResult) => _body.TryDeserializeSequence(node, refSequenceCursor, outResult);
Ejemplo n.º 19
0
 public abstract void GetLength(CodeNodeBuilder node, InArgs <object> target);
 public override void DeserializeSequence(CodeNodeBuilder node, BufferArgs refSequenceCursor) => _body.DeserializeSequence(node, refSequenceCursor);
Ejemplo n.º 21
0
 public abstract void TrySerialize(CodeNodeBuilder node, InArgs <object> target, BufferArgs readOnlySpan, OutArgs <int> outWrittenBytes);
 public static CodeNodeBuilder AddParsingBody(this CodeNodeBuilder builder, IComposerMethodBodyBuilder bodyBuilder, MemberMetaInfo member, ComposerMethodNames names)
 => builder.AddParsingMethods(new ParsingBodyWrapBuilder(member, names, bodyBuilder));
 public override void Serialize(CodeNodeBuilder node, InArgs <object> target, BufferArgs readOnlySpan)
 => node.Return($"{MemberMethod.SerializeState(0)}({parent}, {target}, {readOnlySpan})");
 public override void TryDeserializeSpan(CodeNodeBuilder node, BufferArgs readOnlySpan, OutArgs <int> outReadBytes, OutArgs <object> outResult) => _body.TryDeserializeSpan(node, readOnlySpan, outReadBytes, outResult);
 public override void TryDeserializeSequence(CodeNodeBuilder node, BufferArgs refSequenceCursor, OutArgs <object> outResult)
 => node.Return($"{MemberMethod.TryDeserializeState(0)}({parent}, ref {refSequenceCursor}, out {outResult})");
 public override void GetLength(CodeNodeBuilder node, InArgs <object> target) => _body.GetLength(node, target);
 public override void TrySerialize(CodeNodeBuilder node, InArgs <object> target, BufferArgs readOnlySpan, OutArgs <int> outWrittenBytes)
 => node.Return($"{MemberMethod.TrySerializeState(0)} ({parent}, {target}, {readOnlySpan}, out {outWrittenBytes})");
 public override void Serialize(CodeNodeBuilder node, InArgs <object> target, BufferArgs readOnlySpan) => _body.Serialize(node, target, readOnlySpan);
 public override void DeserializeSpan(CodeNodeBuilder node, BufferArgs readOnlySpan, OutArgs <int> outReadBytes) => _body.DeserializeSpan(node, readOnlySpan, outReadBytes);
 public static CodeNodeBuilder AddFormatterFinalMethods(this CodeNodeBuilder builder, IFormatterParsingMethod <TypeSourceArgs> resolver, MemberMetaInfo member, int index, Func <int, ComposerMethodNames> defaultNames)
 => builder.AddParsingMethods(new FormatterParsingMethodBuilder(resolver, index, member, defaultNames, false));