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); }
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()); }
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 ? "!" : ""; }
/// <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); }
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);
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);
public abstract void GetLength(CodeNodeBuilder node, InArgs <object> target);
public override void DeserializeSequence(CodeNodeBuilder node, BufferArgs refSequenceCursor) => _body.DeserializeSequence(node, refSequenceCursor);
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));