CSCodeGenerationResult GeneratePocoSupport(IActivityMonitor monitor, ICSCodeGenerationContext c, IPocoSupportResult pocoSupport, JsonSerializationCodeGen jsonCodeGen)
        {
            using var g = monitor.OpenInfo($"Generating C# Json serialization code.");

            bool success = true;

            // Generates the factory and the Poco class code.
            foreach (var root in pocoSupport.Roots)
            {
                var factory = c.Assembly.FindOrCreateAutoImplementedClass(monitor, root.PocoFactoryClass);
                foreach (var i in root.Interfaces)
                {
                    var interfaceName = i.PocoInterface.ToCSharpName();
                    var readerName    = "PocoJsonSerializer.IFactoryReader<" + interfaceName + ">";

                    factory.Definition.BaseTypes.Add(new ExtendedTypeName(readerName));
                    factory.Append(interfaceName).Append(' ').Append(readerName).Append(".Read( ref System.Text.Json.Utf8JsonReader r, PocoJsonSerializerOptions options )").NewLine()
                    .Append(" => r.TokenType == System.Text.Json.JsonTokenType.Null ? null : new ")
                    .Append(root.PocoClass.Name).Append("( ref r, options );").NewLine();
                }
                factory.Append("public IPoco ReadTyped( ref System.Text.Json.Utf8JsonReader r, PocoJsonSerializerOptions options ) => new ").Append(root.PocoClass.Name).Append("( ref r, options );").NewLine();

                var pocoClass = c.Assembly.FindOrCreateAutoImplementedClass(monitor, root.PocoClass);

                // Generates the Poco class Read and Write methods.
                // UnionTypes on properties are registered.
                success &= ExtendPocoClass(monitor, root, jsonCodeGen, pocoClass);
            }
            return(success
                    ? new CSCodeGenerationResult(nameof(FinalizeJsonSupport))
                    : CSCodeGenerationResult.Failed);
        }
        public CSCodeGenerationResult Implement(IActivityMonitor monitor, ICSCodeGenerationContext c)
        {
            var pocoDirectory = c.Assembly.FindOrCreateAutoImplementedClass(monitor, typeof(PocoDirectory));
            var jsonCodeGen   = new JsonSerializationCodeGen(monitor, pocoDirectory);

            // Exposes this as a service to others.
            monitor.Info("Exposing JsonSerializationCodeGen in CurrentRun services.");
            c.CurrentRun.ServiceContainer.Add(jsonCodeGen);
            return(new CSCodeGenerationResult(nameof(AllowAllPocoTypes)));
        }
Пример #3
0
        CSCodeGenerationResult DoImplement(IActivityMonitor monitor,
                                           Type classType,
                                           ICSCodeGenerationContext c,
                                           ITypeScope scope,
                                           IPocoSupportResult poco,
                                           Setup.Json.JsonSerializationCodeGen?json = null)
        {
            if (classType != typeof(CrisCommandDirectoryLike))
            {
                throw new InvalidOperationException("Applies only to the CrisCommandDirectoryLike class.");
            }

            // In real Cris, there is a CommandRegistry that registers the commands/handlers/service etc. into an intermediate Entry descriptor
            // with the final (most specific) TResult.
            // Here we shortcut the process and work with the basic IPocoRootInfo:
            if (!poco.OtherInterfaces.TryGetValue(typeof(ICommand), out IReadOnlyList <IPocoRootInfo>?commandPocos))
            {
                commandPocos = Array.Empty <IPocoRootInfo>();
            }

            CodeWriterExtensions.Append(scope, "public ").Append(scope.Name).Append("() : base( CreateCommands() ) {}").NewLine();

            scope.Append("static IReadOnlyList<ICommandModel> CreateCommands()").NewLine()
            .OpenBlock()
            .Append("var list = new ICommandModel[]").NewLine()
            .Append("{").NewLine();
            int idx = 0;

            foreach (var e in commandPocos)
            {
                var f = c.Assembly.FindOrCreateAutoImplementedClass(monitor, e.PocoFactoryClass);
                f.Definition.BaseTypes.Add(new ExtendedTypeName("ICommandModel"));
                f.Append("public Type CommandType => PocoClassType;").NewLine()
                .Append("public int CommandIdx => ").Append(idx++).Append(";").NewLine()
                .Append("public string CommandName => Name;").NewLine()
                .Append("ICommand ICommandModel.Create() => (ICommand)Create();").NewLine();

                // The CommandModel is the _factory field.
                var p = c.Assembly.FindOrCreateAutoImplementedClass(monitor, e.PocoClass);
                p.Append("public ICommandModel CommandModel => _factory;").NewLine();

                scope.Append(p.FullName).Append("._factory,").NewLine();
            }
            scope.Append("};").NewLine()
            .Append("return list;")
            .CloseBlock();

            return(CSCodeGenerationResult.Success);
        }
Пример #4
0
 public CSCodeGenerationResult Implement(IActivityMonitor monitor, ICSCodeGenerationContext c)
 {
     foreach (var poco in c.Assembly.GetPocoSupportResult().Roots)
     {
         foreach (var p in poco.ExternallyImplementedPropertyList)
         {
             if (p.Name == "GlobalSequence")
             {
                 ITypeScope?tB = c.Assembly.FindOrCreateAutoImplementedClass(monitor, poco.PocoClass);
                 tB.Append("public int GlobalSequence => 45343;");
             }
         }
     }
     return(CSCodeGenerationResult.Success);
 }
        public CSCodeGenerationResult Implement(IActivityMonitor monitor,
                                                MethodInfo m,
                                                ICSCodeGenerationContext codeGenContext,
                                                ITypeScope typeBuilder)
        {
            IFunctionScope mB = typeBuilder.CreateOverride(m);

            Debug.Assert(mB.Parent == typeBuilder, "The function is ready to be implemented.");
            if (_attr.IsLambda)
            {
                mB.Append("=> ").Append(_attr.ActualCode).Append(';').NewLine();
            }
            else
            {
                mB.Append(_attr.ActualCode).NewLine();
            }
            return(CSCodeGenerationResult.Success);
        }
 public override CSCodeGenerationResult Implement(IActivityMonitor monitor, Type classType, ICSCodeGenerationContext c, ITypeScope scope)
 {
     c.CurrentRun.ServiceContainer.Add <ISourceCodeHelper>(new SourceCodeHelper());
     return(CSCodeGenerationResult.Success);
 }
 public override CSCodeGenerationResult Implement(IActivityMonitor monitor, Type classType, ICSCodeGenerationContext c, ITypeScope scope)
 {
     monitor.Info($"ActualImpl2: {_h1.IHelpTheCodeGeneration()}, {_h2.IAlsoHelpTheCodeGeneration()}.");
     return(CSCodeGenerationResult.Success);
 }
 public override CSCodeGenerationResult Implement(IActivityMonitor monitor, Type classType, ICSCodeGenerationContext c, ITypeScope scope)
 {
     c.CurrentRun.ServiceContainer.Add(new SourceCodeHelper2());
     return(new CSCodeGenerationResult(typeof(ActualImpl2)));
 }
 public CSCodeGenerationResult Implement(IActivityMonitor monitor, Type classType, ICSCodeGenerationContext c, ITypeScope scope)
 {
     foreach (var p in classType.GetProperties())
     {
         scope.Append("public override ").Append(p.PropertyType.FullName !).Append(" ").Append(p.Name).Append(" => ");
         if (typeof(int).IsAssignableFrom(p.PropertyType))
         {
             scope.Append(_attr.Value);
         }
         else if (typeof(string).IsAssignableFrom(p.PropertyType))
         {
             scope.AppendSourceString($@"Value is ""{_attr.Value}""...");
         }
         else
         {
             scope.Append("default(").AppendCSharpName(p.PropertyType, true, true, true).Append(")");
         }
         scope.Append(";").NewLine();
     }
     return(CSCodeGenerationResult.Success);
 }
Пример #10
0
 CSCodeGenerationResult IAutoImplementor <PropertyInfo> .Implement(IActivityMonitor monitor, PropertyInfo p, ICSCodeGenerationContext c, ITypeScope b)
 {
     throw new NotSupportedException();
 }
        CSCodeGenerationResult AllowAllPocoTypes(IActivityMonitor monitor, ICSCodeGenerationContext c, IPocoSupportResult pocoSupport, JsonSerializationCodeGen jsonCodeGen)
        {
            if (pocoSupport.Roots.Count == 0)
            {
                monitor.Info("No Poco available. Skipping Poco serialization code generation.");
                return(new CSCodeGenerationResult(nameof(FinalizeJsonSupport)));
            }

            using (monitor.OpenInfo($"Allowing Poco Json serialization C# code generation for {pocoSupport.Roots.Count} Pocos."))
            {
                // IPoco and IClosedPoco are not in the "OtherInterfaces".
                jsonCodeGen.AllowInterfaceToUntyped(typeof(IPoco));
                jsonCodeGen.AllowInterfaceToUntyped(typeof(IClosedPoco));
                // Maps the "other Poco interfaces" to "Untyped" object.
                foreach (var other in pocoSupport.OtherInterfaces)
                {
                    jsonCodeGen.AllowInterfaceToUntyped(other.Key);
                }

                bool success = true;
                // Registers TypeInfo for the PocoClass and maps its interfaces to the PocoClass.
                foreach (var root in pocoSupport.Roots)
                {
                    var typeInfo = jsonCodeGen.AllowTypeInfo(root.PocoClass, root.Name, root.PreviousNames)?.Configure(
                        (ICodeWriter write, string variableName)
                        => write.Append("((PocoJsonSerializer.IWriter)").Append(variableName).Append(").Write( w, false, options );"),
                        (ICodeWriter read, string variableName, bool assignOnly, bool isNullable) =>
                    {
                        if (!assignOnly)
                        {
                            if (isNullable)
                            {
                                read.Append("if( ").Append(variableName).Append(" != null ) ").NewLine();
                            }
                            read.Append("((").AppendCSharpName(root.PocoClass, true, true, true).Append(')').Append(variableName).Append(')').Append(".Read( ref r, options );");
                            if (isNullable)
                            {
                                read.NewLine().Append("else").NewLine();
                                assignOnly = true;
                            }
                        }
                        if (assignOnly)
                        {
                            read.Append(variableName)
                            .Append(" = new ").AppendCSharpName(root.PocoClass, true, true, true)
                            .Append("( ref r, options );");
                        }
                    });
                    if (typeInfo != null)
                    {
                        foreach (var i in root.Interfaces)
                        {
                            jsonCodeGen.AllowTypeAlias(i.PocoInterface.GetNullableTypeTree(), typeInfo);
                        }
                    }
                    else
                    {
                        success = false;
                    }
                }
                return(success
                        ? new CSCodeGenerationResult(nameof(GeneratePocoSupport))
                        : CSCodeGenerationResult.Failed);
            }
        }
 bool FinalizeImpl(IActivityMonitor monitor, Type classType, ICSCodeGenerationContext c, ITypeScope scope, ISourceCodeHelper helper)
 {
     monitor.Info($"AutoImpl in another pass: {helper.IHelpTheCodeGeneration()}.");
     return(true);
 }
 public override CSCodeGenerationResult Implement(IActivityMonitor monitor, Type classType, ICSCodeGenerationContext c, ITypeScope scope)
 {
     return(new CSCodeGenerationResult(nameof(DoImplement)));
 }
Пример #14
0
 public override CSCodeGenerationResult Implement(IActivityMonitor monitor, Type classType, ICSCodeGenerationContext c, ITypeScope scope)
 {
     // We need the IJsonSerializationCodeGen service to register command result type (for real Cris, here we don't handle results).
     return(new CSCodeGenerationResult(nameof(DoImplement)));
 }
Пример #15
0
        bool GenerateSourceCodeFirstPass(IActivityMonitor monitor,
                                         ICSCodeGenerationContext codeGenContext,
                                         string?informationalVersion,
                                         List <MultiPassCodeGeneration> collector,
                                         IEnumerable <ICSCodeGenerator> aspectsGenerators)
        {
            Debug.Assert(EngineMap != null);
            Debug.Assert(codeGenContext.Assembly == _tempAssembly, "CodeGenerationContext mismatch.");
            try
            {
                Debug.Assert(_valueCollector != null);
                IReadOnlyList <ActivityMonitorSimpleCollector.Entry>?errorSummary = null;
                using (monitor.OpenInfo($"Generating source code (first pass) for: {codeGenContext.CurrentRun.ConfigurationGroup.Names}."))
                    using (monitor.CollectEntries(entries => errorSummary = entries))
                    {
                        using (monitor.OpenInfo("Registering direct properties as PostBuildProperties."))
                        {
                            foreach (MutableItem item in EngineMap.StObjs.OrderedStObjs)
                            {
                                item.RegisterRemainingDirectPropertiesAsPostBuildProperties(_valueCollector);
                            }
                        }

                        // Retrieves CK._g workspace.
                        var ws = _tempAssembly.Code;
                        // Gets the global name space and starts with the informational version (if any),
                        // and, once for all, basic namespaces that we always want available.
                        var global = ws.Global;

                        if (!string.IsNullOrWhiteSpace(informationalVersion))
                        {
                            global.BeforeNamespace.Append("[assembly:System.Reflection.AssemblyInformationalVersion(")
                            .AppendSourceString(informationalVersion)
                            .Append(")]")
                            .NewLine();
                        }

                        // Injects System.Reflection and setup assemblies into the
                        // workspace that will be used to generate source code.
                        ws.EnsureAssemblyReference(typeof(BindingFlags));
                        if (CKTypeResult.Assemblies.Count > 0)
                        {
                            ws.EnsureAssemblyReference(CKTypeResult.Assemblies);
                        }
                        else
                        {
                            ws.EnsureAssemblyReference(typeof(StObjContextRoot).Assembly);
                        }

                        // Injects, once for all, basic namespaces that we always want available into the global namespace.
                        global.GeneratedByComment().NewLine()
                        .EnsureUsing("CK.Core")
                        .EnsureUsing("System")
                        .EnsureUsing("System.Collections.Generic")
                        .EnsureUsing("System.Linq")
                        .EnsureUsing("System.Threading.Tasks")
                        .EnsureUsing("System.Text")
                        .EnsureUsing("System.Reflection");

                        global.Append("// We don't generate nullable enabled code and we disable all warnings.").NewLine()
                        .Append("#nullable disable").NewLine()
                        .Append("#pragma warning disable").NewLine();

                        // Generates the Signature attribute implementation.
                        var nsStObj = global.FindOrCreateNamespace("CK.StObj");
                        nsStObj
                        .Append("[AttributeUsage(AttributeTargets.Assembly)]").NewLine()
                        .Append(@"internal sealed class SignatureAttribute : Attribute")
                        .OpenBlock()
                        .Append("public SignatureAttribute( string s ) {}").NewLine()
                        .Append("public readonly static (SHA1Value Signature, IReadOnlyList<string> Names) V = ( SHA1Value.Parse( (string)typeof( SignatureAttribute ).Assembly.GetCustomAttributesData().First( a => a.AttributeType == typeof( SignatureAttribute ) ).ConstructorArguments[0].Value )").NewLine()
                        .Append(", ").AppendArray(EngineMap.Names).Append(" );")
                        .CloseBlock();

                        // Generates the StObjContextRoot implementation.
                        GenerateStObjContextRootSource(monitor, nsStObj, EngineMap.StObjs.OrderedStObjs);

                        // Calls all ICSCodeGenerator items.
                        foreach (var g in EngineMap.AllTypesAttributesCache.Values.SelectMany(attr => attr.GetAllCustomAttributes <ICSCodeGenerator>())
                                 .Concat(aspectsGenerators))
                        {
                            var second = MultiPassCodeGeneration.FirstPass(monitor, g, codeGenContext).SecondPass;
                            if (second != null)
                            {
                                collector.Add(second);
                            }
                        }

                        // Asks every ImplementableTypeInfo to generate their code.
                        // This step MUST always be done, even if CompileOption is None and GenerateSourceFiles is false
                        // since during this step, side effects MAY occur (this is typically the case of the first run where
                        // the "reality cache" is created).
                        foreach (var t in CKTypeResult.TypesToImplement)
                        {
                            t.RunFirstPass(monitor, codeGenContext, collector);
                        }
                    }
                if (errorSummary != null)
                {
                    using (monitor.OpenFatal($"{errorSummary.Count} error(s). Summary:"))
                    {
                        foreach (var e in errorSummary)
                        {
                            monitor.Trace($"{e.MaskedLevel} - {e.Text}");
                        }
                    }
                    return(false);
                }
                return(true);
            }
            catch (Exception ex)
            {
                monitor.Error("While generating final source code.", ex);
                return(false);
            }
        }
 void WithJsonCodeGen(IActivityMonitor monitor, ICSCodeGenerationContext codeGenContext, JsonSerializationCodeGen json)
 {
     json.TypeInfoRequired += OnTypeInfoRequired;
 }
 CSCodeGenerationResult ICSCodeGenerator.Implement(IActivityMonitor monitor, ICSCodeGenerationContext codeGenContext) => new CSCodeGenerationResult(nameof(WithJsonCodeGen));
 CSCodeGenerationResult DoImplement(IActivityMonitor monitor, Type classType, ICSCodeGenerationContext c, ITypeScope scope, ISourceCodeHelper helper)
 {
     c.Should().NotBeNull();
     scope.Should().NotBeNull();
     monitor.Info($"AutoImpl2: {helper.IHelpTheCodeGeneration()}.");
     return(new CSCodeGenerationResult(nameof(FinalizeImpl)));
 }
            public CSCodeGenerationResult Implement(IActivityMonitor monitor, MethodInfo m, ICSCodeGenerationContext c, ITypeScope b)
            {
                IFunctionScope mB = b.CreateOverride(m);

                mB.Parent.Should().BeSameAs(b, "The function is ready to be implemented.");

                if (IsLambda)
                {
                    mB.Append("=> ").Append(ActualCode).Append(';').NewLine();
                }
                else
                {
                    mB.Append(ActualCode);
                }

                return(CSCodeGenerationResult.Success);
            }
        /// <summary>
        /// Generates the <paramref name="scope"/> that is the PocoDirectory_CK class and
        /// all the factories (<see cref="IPocoFactory"/> implementations) and the Poco class (<see cref="IPoco"/> implementations).
        /// </summary>
        /// <param name="monitor">The monitor to use.</param>
        /// <param name="classType">The <see cref="PocoDirectory"/> type.</param>
        /// <param name="c">Code generation context.</param>
        /// <param name="scope">The PocoDirectory_CK type scope.</param>
        /// <returns>Always <see cref="CSCodeGenerationResult.Success"/>.</returns>
        public override CSCodeGenerationResult Implement(IActivityMonitor monitor, Type classType, ICSCodeGenerationContext c, ITypeScope scope)
        {
            Debug.Assert(scope.FullName == "CK.Core.PocoDirectory_CK", "We can use the PocoDirectory_CK type name to reference the PocoDirectory implementation.");

            IPocoSupportResult r = c.Assembly.GetPocoSupportResult();

            Debug.Assert(r == c.CurrentRun.ServiceContainer.GetService(typeof(IPocoSupportResult)), "The PocoSupportResult is also available at the GeneratedBinPath.");

            // PocoDirectory_CK class.
            scope.GeneratedByComment().NewLine()
            .FindOrCreateFunction("internal PocoDirectory_CK()")
            .Append("Instance = this;").NewLine();

            scope.Append("internal static PocoDirectory_CK Instance;").NewLine()
            // The _factories field
            .Append("static readonly Dictionary<string,IPocoFactory> _factoriesN = new Dictionary<string,IPocoFactory>( ").Append(r.NamedRoots.Count).Append(" );").NewLine()
            .Append("static readonly Dictionary<Type,IPocoFactory> _factoriesT = new Dictionary<Type,IPocoFactory>( ").Append(r.AllInterfaces.Count).Append(" );").NewLine()
            .Append("public override IPocoFactory Find( string name ) => _factoriesN.GetValueOrDefault( name );").NewLine()
            .Append("public override IPocoFactory Find( Type t ) => _factoriesT.GetValueOrDefault( t );").NewLine()
            .Append("internal static void Register( IPocoFactory f )").OpenBlock()
            .Append("_factoriesN.Add( f.Name, f );").NewLine()
            .Append("foreach( var n in f.PreviousNames ) _factoriesN.Add( n, f );").NewLine()
            .Append("foreach( var i in f.Interfaces ) _factoriesT.Add( i, f );").NewLine()
            .CloseBlock();

            if (r.AllInterfaces.Count == 0)
            {
                return(CSCodeGenerationResult.Success);
            }

            foreach (var root in r.Roots)
            {
                // PocoFactory class.
                var tFB = c.Assembly.FindOrCreateAutoImplementedClass(monitor, root.PocoFactoryClass);
                tFB.Definition.Modifiers |= Modifiers.Sealed;
                string factoryClassName = tFB.Definition.Name.Name;

                // Poco class.
                var tB = c.Assembly.FindOrCreateAutoImplementedClass(monitor, root.PocoClass);
                tB.Definition.Modifiers |= Modifiers.Sealed;

                // The Poco's static _factory field is internal and its type is the exact class: extended code
                // can refer to the _factory to access the factory extended code without cast.
                //
                // This static internal field is an awful shortcut but it makes things simpler and more efficient
                // than looking up the factory in the DI (and downcasting it) each time we need it.
                // This simplification has been done for Cris Command implementation: a ICommand exposes
                // its ICommandModel: we used to inject the ICommandModel (that is the extended PocoFactory) in the ICommand
                // PocoClass ctor from the factory methods. It worked but it was complex... and, eventually, there
                // can (today) but most importantly there SHOULD, be only one StObjMap/Concrete generated code in an
                // assembly. Maybe one day, the StObj instances themselves can be made static (since they are some kind of
                // "absolute singletons").
                //
                // Note to myself: this "static shortcut" is valid because we are on a "final generation", not on a
                // local, per-module, intermediate, code generation like .Net 5 Code Generators.
                // How this kind of shortcuts could be implemented with .Net 5 Code Generators? It seems that it could but
                // there will be as many "intermediate statics" as there are "levels of assemblies"? Or, there will be only
                // one static (the first one) and the instance will be replaced by the subsequent assemblies? In all cases,
                // diamond problem will have to be ultimately resolved at the final leaf... Just like we do!
                //
                tB.Append("internal static ").Append(tFB.Name).Append(" _factory;")
                .NewLine();
                tB.Append("IPocoFactory IPocoGeneratedClass.Factory => _factory;").NewLine();

                // Always create the constructor so that other code generators
                // can always find it.
                // We support the interfaces here: if other participants have already created this type, it is
                // up to us, here, to handle the "exact" type definition.
                tB.Definition.BaseTypes.Add(new ExtendedTypeName("IPocoGeneratedClass"));
                tB.Definition.BaseTypes.AddRange(root.Interfaces.Select(i => new ExtendedTypeName(i.PocoInterface.ToCSharpName())));

                IFunctionScope ctorB = tB.CreateFunction($"public {root.PocoClass.Name}()");

                foreach (var p in root.PropertyList)
                {
                    Type propType    = p.PropertyType;
                    bool isUnionType = p.PropertyUnionTypes.Any();

                    var    typeName  = propType.ToCSharpName();
                    string fieldName = "_v" + p.Index;
                    tB.Append(typeName).Space().Append(fieldName);
                    if (p.DefaultValueSource == null)
                    {
                        tB.Append(";");
                    }
                    else
                    {
                        tB.Append(" = ").Append(p.DefaultValueSource).Append(";");
                    }
                    tB.NewLine();

                    tB.Append("public ").Append(typeName).Space().Append(p.PropertyName);
                    Debug.Assert(!p.IsReadOnly || p.DefaultValueSource == null, "Readonly with [DefaultValue] has already raised an error.");

                    if (p.IsReadOnly)
                    {
                        // Generates in constructor.
                        r.GenerateAutoInstantiatedNewAssignation(ctorB, fieldName, p.PropertyType);
                    }

                    tB.OpenBlock()
                    .Append("get => ").Append(fieldName).Append(";").NewLine();

                    if (!p.IsReadOnly)
                    {
                        tB.Append("set")
                        .OpenBlock();

                        bool isTechnicallyNullable = p.PropertyNullableTypeTree.Kind.IsTechnicallyNullable();
                        bool isNullable            = p.PropertyNullableTypeTree.Kind.IsNullable();

                        if (isTechnicallyNullable && !isNullable)
                        {
                            tB.Append("if( value == null ) throw new ArgumentNullException();").NewLine();
                        }

                        if (isUnionType)
                        {
                            if (isNullable)
                            {
                                tB.Append("if( value != null )")
                                .OpenBlock();
                            }
                            tB.Append("Type tV = value.GetType();").NewLine()
                            .Append("if( !_c").Append(fieldName)
                            .Append(".Any( t => t.IsAssignableFrom( tV ) ))")
                            .OpenBlock()
                            .Append("throw new ArgumentException( $\"Unexpected Type '{tV}' in UnionType. Allowed types are: ")
                            .Append(p.PropertyUnionTypes.Select(tU => tU.ToString()).Concatenate())
                            .Append(".\");")
                            .CloseBlock();
                            if (isNullable)
                            {
                                tB.CloseBlock();
                            }
                        }
                        tB.Append(fieldName).Append(" = value;")
                        .CloseBlock();
                    }
                    tB.CloseBlock();

                    if (isUnionType)
                    {
                        tB.Append("static readonly Type[] _c").Append(fieldName).Append("=").AppendArray(p.PropertyUnionTypes.Select(u => u.Type)).Append(";").NewLine();
                    }
                }

                // PocoFactory class.

                tFB.Append("PocoDirectory IPocoFactory.PocoDirectory => PocoDirectory_CK.Instance;").NewLine();

                tFB.Append("public Type PocoClassType => typeof(").Append(root.PocoClass.Name).Append(");")
                .NewLine();

                tFB.Append("public IPoco Create() => new ").Append(root.PocoClass.Name).Append("();")
                .NewLine();

                tFB.Append("public string Name => ").AppendSourceString(root.Name).Append(";")
                .NewLine();

                tFB.Append("public IReadOnlyList<string> PreviousNames => ").AppendArray(root.PreviousNames).Append(";")
                .NewLine();

                tFB.Append("public IReadOnlyList<Type> Interfaces => ").AppendArray(root.Interfaces.Select(i => i.PocoInterface)).Append(";")
                .NewLine();

                tFB.CreateFunction("public " + factoryClassName + "()")
                .Append("PocoDirectory_CK.Register( this );").NewLine()
                .Append(tB.Name).Append("._factory = this;");

                foreach (var i in root.Interfaces)
                {
                    tFB.Definition.BaseTypes.Add(new ExtendedTypeName(i.PocoFactoryInterface.ToCSharpName()));
                    tFB.AppendCSharpName(i.PocoInterface, true, true, true)
                    .Space()
                    .AppendCSharpName(i.PocoFactoryInterface, true, true, true)
                    .Append(".Create() => new ").AppendCSharpName(i.Root.PocoClass, true, true, true).Append("();")
                    .NewLine();
                }
            }
            return(CSCodeGenerationResult.Success);
        }
Пример #21
0
 /// <summary>
 /// See <see cref="ICSCodeGenerator.Implement"/>.
 /// This default implementation returns <see cref="CSCodeGenerationResult.Success"/>: the abstract <see cref="Implement(IActivityMonitor, Type, ICSCodeGenerationContext, ITypeScope)"/> "type
 /// based" method must do the job.
 /// </summary>
 /// <param name="monitor">The monitor to use.</param>
 /// <param name="p">The property to implement.</param>
 /// <param name="c">Code generation context with its Dynamic assembly being implemented.</param>
 /// <param name="typeBuilder">The type builder to use.</param>
 /// <returns>Always <see cref="CSCodeGenerationResult.Success"/> at this level.</returns>
 public virtual CSCodeGenerationResult Implement(IActivityMonitor monitor, PropertyInfo p, ICSCodeGenerationContext c, ITypeScope typeBuilder) => CSCodeGenerationResult.Success;
Пример #22
0
 /// <summary>
 /// Must implement the full type.
 /// </summary>
 /// <param name="monitor">The monitor to use.</param>
 /// <param name="classType">The full base type to implement.</param>
 /// <param name="c">Code generation context with its Dynamic assembly being implemented.</param>
 /// <param name="scope">The type builder of the specialized class to implement.</param>
 /// <returns></returns>
 public abstract CSCodeGenerationResult Implement(IActivityMonitor monitor, Type classType, ICSCodeGenerationContext c, ITypeScope scope);
 // We choose to implement all the properties as a whole in Implement method below: by returning CSCodeGenerationResult.Success
 // we tell the engine: "Okay, I handled it, please continue your business."
 // (We can also implement each property here and do nothing in the Implement method.)
 CSCodeGenerationResult IAutoImplementor <PropertyInfo> .Implement(IActivityMonitor monitor, PropertyInfo p, ICSCodeGenerationContext c, ITypeScope typeBuilder) => CSCodeGenerationResult.Success;
Пример #24
0
 public override CSCodeGenerationResult Implement(IActivityMonitor monitor, Type classType, ICSCodeGenerationContext c, ITypeScope scope)
 {
     return(CSCodeGenerationResult.Success);
 }
 public CSCodeGenerationResult Implement(IActivityMonitor monitor, ICSCodeGenerationContext codeGenContext)
 {
     Called = true;
     return(CSCodeGenerationResult.Success);
 }