Esempio n. 1
0
        public static IEnumerable<IDocumentStorage> Build(IDocumentSchema schema, DocumentMapping[] mappings)
        {
            // Generate the actual source code
            var code = GenerateDocumentStorageCode(mappings);

            var generator = new AssemblyGenerator();

            // Tell the generator which other assemblies that it should be referencing 
            // for the compilation
            generator.ReferenceAssembly(Assembly.GetExecutingAssembly());
            generator.ReferenceAssemblyContainingType<NpgsqlConnection>();
            generator.ReferenceAssemblyContainingType<QueryModel>();
            generator.ReferenceAssemblyContainingType<DbCommand>();
            generator.ReferenceAssemblyContainingType<Component>();
            generator.ReferenceAssemblyContainingType<DbDataReader>();

            mappings.Select(x => x.DocumentType.Assembly).Distinct().Each(assem => generator.ReferenceAssembly(assem));

            // build the new assembly -- this will blow up if there are any
            // compilation errors with the list of errors and the actual code

            var assembly = generator.Generate(code);

            return assembly
                .GetExportedTypes()
                .Where(x => x.IsConcreteTypeOf<IDocumentStorage>())
                .Select(x => BuildStorageObject(schema, mappings, x));
        }
Esempio n. 2
0
        public static IEnumerable <IDocumentStorage> Build(IDocumentSchema schema, DocumentMapping[] mappings)
        {
            // Generate the actual source code
            var code = GenerateDocumentStorageCode(mappings);

            var generator = new AssemblyGenerator();

            // Tell the generator which other assemblies that it should be referencing
            // for the compilation
            generator.ReferenceAssembly(Assembly.GetExecutingAssembly());
            generator.ReferenceAssemblyContainingType <NpgsqlConnection>();
            generator.ReferenceAssemblyContainingType <QueryModel>();
            generator.ReferenceAssemblyContainingType <DbCommand>();
            generator.ReferenceAssemblyContainingType <Component>();
            generator.ReferenceAssemblyContainingType <DbDataReader>();

            mappings.Select(x => x.DocumentType.Assembly).Distinct().Each(assem => generator.ReferenceAssembly(assem));

            // build the new assembly -- this will blow up if there are any
            // compilation errors with the list of errors and the actual code

            var assembly = generator.Generate(code);

            return(assembly
                   .GetExportedTypes()
                   .Where(x => x.IsConcreteTypeOf <IDocumentStorage>())
                   .Select(x => BuildStorageObject(schema, mappings, x)));
        }
Esempio n. 3
0
        public static IEnumerable<IDocumentStorage> Build(IDocumentSchema schema, DocumentMapping[] mappings)
        {
            var code = GenerateDocumentStorageCode(mappings);

            var generator = new AssemblyGenerator();
            generator.ReferenceAssembly(Assembly.GetExecutingAssembly());
            generator.ReferenceAssemblyContainingType<NpgsqlConnection>();
            generator.ReferenceAssemblyContainingType<QueryModel>();
            generator.ReferenceAssemblyContainingType<DbCommand>();
            generator.ReferenceAssemblyContainingType<Component>();

            mappings.Select(x => x.DocumentType.Assembly).Distinct().Each(assem => generator.ReferenceAssembly(assem));

            var assembly = generator.Generate(code);

            return assembly
                .GetExportedTypes()
                .Where(x => x.IsConcreteTypeOf<IDocumentStorage>())
                .Select(x =>
                {
                    var docType =
                        x.FindInterfaceThatCloses(typeof (IdAssignment<>)).GetGenericArguments().Single();

                    var mapping = mappings.Single(m => m.DocumentType == docType);

                    var arguments = mapping.IdStrategy.ToArguments().Select(arg => arg.GetValue(schema)).ToArray();

                    var ctor = x.GetConstructors().Single();

                    return ctor.Invoke(arguments).As<IDocumentStorage>();
                });
        }
Esempio n. 4
0
        // Public methods
        ///////////////////////////

        public static Action Create(Ecs.Internals ecs, MethodInfo systemInfo)
        {
            var systemName = $"{systemInfo.DeclaringType}.{systemInfo.Name}";
            var arguments  = systemInfo.GetParameters()
                             .Select(p => GetArgumentData(ecs, p))
                             .ToArray();

            if (arguments.Length == 0)
            {
                return(() => systemInfo.Invoke(null, null));
            }
            var resources = arguments
                            .Where(a => a.isResource)
                            .ToArray();
            var components = arguments
                             .Where(a => !a.isResource)
                             .ToArray();
            var src = default(string);

            if (components.Length > 0)
            {
                src = ForEachSource(ecs, arguments, resources, components);
            }
            else
            {
                src = ResourceOnlySource(ecs, resources);
            }
            var asmGen = new AssemblyGenerator();

            asmGen.ReferenceAssemblyByName("System");
            asmGen.ReferenceAssemblyByName("System.Collections");
            asmGen.ReferenceAssemblyByName("System.Reflection");
            asmGen.ReferenceAssemblyContainingType(typeof(Ecs));
            src = asmGen.Format(src);
            var startTime = TimeNow();

            var(assembly, errors) = asmGen.Generate(src);
            if (errors != null)
            {
                var sb = new System.Text.StringBuilder();
                sb.Append($"encountered error(s) compiling system runner for {systemName}");
                foreach (var error in errors)
                {
                    sb.Append($"\n  {error.Replace("\n", "\n  ")}");
                }
                var srcLines = src.Split("\n");
                for (var i = 0; i < srcLines.Length; i++)
                {
                    sb.Append($"\n{i+1}\t{srcLines[i]}");
                }
                throw new Exception(sb.ToString());
            }
            var runner   = assembly.GetType("Runner");
            var duration = TimeNow() - startTime;

            Console.WriteLine($"generated system runner for {systemName} in {duration}ms:\n  {src.Replace("\n", "\n  ")}");
            runner.GetMethod("Initialize").Invoke(null, new object[] { ecs, systemInfo });
            return((Action)runner.GetMethod("Run").CreateDelegate(typeof(Action)));
        }
Esempio n. 5
0
        public static IEnumerable<IDocumentStorage> Build(DocumentMapping[] mappings)
        {
            var code = GenerateDocumentStorageCode(mappings);

            var generator = new AssemblyGenerator();
            generator.ReferenceAssembly(Assembly.GetExecutingAssembly());
            generator.ReferenceAssemblyContainingType<NpgsqlConnection>();
            generator.ReferenceAssemblyContainingType<QueryModel>();
            generator.ReferenceAssemblyContainingType<DbCommand>();
            generator.ReferenceAssemblyContainingType<Component>();

            mappings.Select(x => x.DocumentType.Assembly).Distinct().Each(assem => generator.ReferenceAssembly(assem));

            var assembly = generator.Generate(code);

            return assembly
                .GetExportedTypes()
                .Where(x => x.IsConcreteTypeOf<IDocumentStorage>())
                .Select(x => Activator.CreateInstance(x).As<IDocumentStorage>());
        }
Esempio n. 6
0
        public static IEnumerable <IDocumentStorage> Build(IDocumentSchema schema, IDocumentMapping[] mappings)
        {
            // Generate the actual source code
            var code = GenerateDocumentStorageCode(mappings);

            var generator = new AssemblyGenerator();

            // Tell the generator which other assemblies that it should be referencing
            // for the compilation
            generator.ReferenceAssembly(Assembly.GetExecutingAssembly());
            generator.ReferenceAssemblyContainingType <NpgsqlConnection>();
            generator.ReferenceAssemblyContainingType <QueryModel>();
            generator.ReferenceAssemblyContainingType <DbCommand>();
            generator.ReferenceAssemblyContainingType <Component>();
            generator.ReferenceAssemblyContainingType <DbDataReader>();

            mappings.Select(x => x.DocumentType.Assembly).Distinct().Each(assem => generator.ReferenceAssembly(assem));

            // build the new assembly -- this will blow up if there are any
            // compilation errors with the list of errors and the actual code

            var assembly = generator.Generate(code);

            return(assembly
                   .GetExportedTypes()
                   .Where(x => x.IsConcreteTypeOf <IDocumentStorage>())
                   .Select(x =>
            {
                var docType =
                    x.FindInterfaceThatCloses(typeof(IdAssignment <>)).GetGenericArguments().Single();

                var mapping = mappings.Single(m => m.DocumentType == docType);

                var arguments = mapping.ToArguments().Select(arg => arg.GetValue(schema)).ToArray();

                var ctor = x.GetConstructors().Single();

                return ctor.Invoke(arguments).As <IDocumentStorage>();
            }));
        }
Esempio n. 7
0
        public static IEnumerable<IDocumentStorage> Build(IDocumentSchema schema, IDocumentMapping[] mappings)
        {
            // Generate the actual source code
            var code = GenerateDocumentStorageCode(mappings);

            var generator = new AssemblyGenerator();

            // Tell the generator which other assemblies that it should be referencing 
            // for the compilation
            generator.ReferenceAssembly(Assembly.GetExecutingAssembly());
            generator.ReferenceAssemblyContainingType<NpgsqlConnection>();
            generator.ReferenceAssemblyContainingType<QueryModel>();
            generator.ReferenceAssemblyContainingType<DbCommand>();
            generator.ReferenceAssemblyContainingType<Component>();
            generator.ReferenceAssemblyContainingType<DbDataReader>();

            mappings.Select(x => x.DocumentType.Assembly).Distinct().Each(assem => generator.ReferenceAssembly(assem));

            // build the new assembly -- this will blow up if there are any
            // compilation errors with the list of errors and the actual code

            var assembly = generator.Generate(code);

            return assembly
                .GetExportedTypes()
                .Where(x => x.IsConcreteTypeOf<IDocumentStorage>())
                .Select(x =>
                {
                    var docType =
                        x.FindInterfaceThatCloses(typeof (IdAssignment<>)).GetGenericArguments().Single();

                    var mapping = mappings.Single(m => m.DocumentType == docType);

                    var arguments = mapping.ToArguments().Select(arg => arg.GetValue(schema)).ToArray();

                    var ctor = x.GetConstructors().Single();

                    return ctor.Invoke(arguments).As<IDocumentStorage>();
                });
        }
Esempio n. 8
0
        public static IEnumerable <IDocumentStorage> Build(DocumentMapping[] mappings)
        {
            var code = GenerateDocumentStorageCode(mappings);

            var generator = new AssemblyGenerator();

            generator.ReferenceAssembly(Assembly.GetExecutingAssembly());
            generator.ReferenceAssemblyContainingType <NpgsqlConnection>();
            generator.ReferenceAssemblyContainingType <QueryModel>();
            generator.ReferenceAssemblyContainingType <DbCommand>();
            generator.ReferenceAssemblyContainingType <Component>();

            mappings.Select(x => x.DocumentType.Assembly).Distinct().Each(assem => generator.ReferenceAssembly(assem));


            var assembly = generator.Generate(code);

            return(assembly
                   .GetExportedTypes()
                   .Where(x => x.IsConcreteTypeOf <IDocumentStorage>())
                   .Select(x => Activator.CreateInstance(x).As <IDocumentStorage>()));
        }
Esempio n. 9
0
        static (Action, bool) Compile(string fileName)
        {
            var startTime = Time.Now();
            var source    = File.ReadAllText(fileName);
            var asmGen    = new AssemblyGenerator();

            asmGen.ReferenceAssemblyByName("System.Collections");
            asmGen.ReferenceAssemblyByName("System.Linq");
            asmGen.ReferenceAssemblyContainingType(typeof(Program));
            source = asmGen.Format(source);
            var(assembly, errors) = asmGen.Generate(source);
            if (errors != null)
            {
                Log.Error($"compilation error:\n{String.Join("\n", errors)}");
                return(null, false);
            }
            var scriptType = assembly.GetType("Script");
            var mainMethod = scriptType.GetMethod("Main", BindingFlags.NonPublic | BindingFlags.Static);
            var run        = (Action)mainMethod.CreateDelegate(typeof(Action));
            var duration   = Time.Now() - startTime;

            Log.Info($"compiled script {fileName} in {duration:F2}s");
            return(run, true);
        }
Esempio n. 10
0
        public ObjectBinder(IDictionary <Expression <Func <TSource, object> >, Expression <Func <TCommon, object> > > map,
                            AssemblyGenerator assemblyGenerator)
        {
            var sourceType = typeof(TSource);
            var commonType = typeof(TCommon);

            Guard.Argument(commonType)
            .Require(x => x.IsInterface || x.GetConstructor(Type.EmptyTypes) != null,
                     x => "Common type must be either an interface or provide parameterless constructor"
                     );

            assemblyGenerator.ReferenceAssemblyContainingType <TSource>();
            assemblyGenerator.ReferenceAssemblyContainingType <TCommon>();

            var visitedCommonProperties = ImmutableList <PropertyInfo> .Empty;

            var(shadowField, constructorArg) = ("_sourceRef", "sourceRef");

            var assembly = assemblyGenerator.Generate(opt =>
            {
                var className = $"{commonType.Name}_proxy_{_count++}";
                opt.UsingNamespace <TSource>();
                opt.UsingNamespace <TCommon>();

                opt.Namespace($"LamarGenerated.Proxy.{sourceType.Name}_{commonType.Name}");
                opt.StartClass(className, typeof(TCommon));

                // Shadow field
                opt.Write($"private readonly {sourceType.FullNameInCode()} {shadowField};");
                opt.BlankLine();

                // Constructor
                opt.Write($"BLOCK:public {className} ({sourceType.FullNameInCode()} {constructorArg})");
                opt.Write($"{shadowField} = {constructorArg};");
                opt.FinishBlock();

                foreach (var(key, value) in map)
                {
                    var(prop1, prop2) = (ResolveMemberExpression(key), ResolveMemberExpression(value));

                    visitedCommonProperties = visitedCommonProperties.Add(prop2);

                    Guard.Argument((prop1, prop2))
                    .Require(x => x.Item1 != null)
                    .Require(x => x.Item2 != null)
                    .Require(x => x.Item1.PropertyType == x.Item2.PropertyType,
                             tuple =>
                             $"Property types between {tuple.Item1.PropertyType} and {tuple.Item2.PropertyType} do not match");

                    // If TCommon is not an interface and if property of common is virtual, then we can override it else
                    // it causes property duplication as overriding property is not possible
                    var needsOverride = false;

                    if (!commonType.IsInterface)
                    {
                        needsOverride = prop2.GetGetMethod().IsVirtual
                            ? true
                            : throw new Exception($"TCommon type is not an interface and property {prop2.Name} of" +
                                                  "Common type is not virtual hence it causes property duplication");
                    }

                    opt.Write(
                        $"public {(needsOverride ? "override" : string.Empty)} {prop1.PropertyType.FullNameInCode()} {prop2.Name} " +
                        "{" +
                        $@" get {{ return {shadowField}.{prop1.Name};  }} " +
                        $@" set {{ {shadowField}.{prop1.Name} = value; }} " +
                        "}");

                    opt.BlankLine();
                }

                // If common type is not an interface, hence we need to add the properties, otherwise, they will be inherited
                if (commonType.IsInterface)
                {
                    // Add the rest of properties that do not needed be bound
                    foreach (var propertyInfo in commonType.GetProperties().Except(visitedCommonProperties))
                    {
                        opt.Write(
                            $"public {propertyInfo.PropertyType.FullNameInCode()} {propertyInfo.Name} {{ get; set; }} ");

                        opt.BlankLine();
                    }
                }

                opt.FinishBlock(); // Finish the class
                opt.FinishBlock(); // Finish the namespace
            });

            BoundType = assembly.GetExportedTypes().Single();
        }