예제 #1
0
        private void GenerateStaticConstructorFor(
            PropertyTypeNode c,
            StringBuffer gen)
        {
            var containerTypeName = c.TypeName;

            gen.Append(' ', Style.Space * 1);
            gen.Append($"static {containerTypeName} (){Environment.NewLine}");
            gen.Append(' ', Style.Space * 1);
            gen.Append("{");
            gen.Append(Environment.NewLine);

            // Handle property initializers generation stage

            StaticConstructorStagePrePostFragments stageFragments;

            if (StaticConstructorInitializerFragments.TryGetValue(ConstructorStage.PropertyInitializationStage, out stageFragments))
            {
                var fragments = stageFragments.InStageFragments;

                if (fragments.Count != 0)
                {
                    gen.Append(' ', Style.Space * 2);
                    gen.Append("// Property wrappers initializers");
                    gen.Append(Environment.NewLine);

                    GenerateFragments(fragments, gen);
                }

                // Handle property initializers post generation stage (user hooks etc.)

                fragments = stageFragments.PostStageFragments;

                if (fragments.Count != 0)
                {
                    gen.Append(Environment.NewLine);
                    gen.Append(' ', Style.Space * 2);
                    gen.Append("// User Hooks");
                    gen.Append(Environment.NewLine);

                    GenerateFragments(fragments, gen);
                }
            }

            gen.Append(Environment.NewLine);
            gen.Append(' ', Style.Space * 2);
            gen.Append("// Freeze property bag items");

            foreach (var item in PropertyBagItemNames)
            {
                gen.Append(Environment.NewLine);
                gen.Append(' ', Style.Space * 2);
                gen.Append($"// {item}.Freeze();");
            }
            gen.Append(Environment.NewLine);

            gen.Append(' ', Style.Space * 1);
            gen.Append("}"); gen.Append(Environment.NewLine);
        }
        public override void OnGenerateStaticConstructorForContainer(PropertyTypeNode container)
        {
            TypeDefinition type = null;

            if (!_typeDefinitionPerPropertyNodeMap.TryGetValue(container, out type))
            {
                // @TODO error
                return;
            }

            try
            {
                // Check if there is one already
                MethodDefinition staticConstructor = type.GetMethods().FirstOrDefault(c => c.Name == ".cctor");

                bool constructorCreated = staticConstructor == null;
                if (staticConstructor == null)
                {
                    const MethodAttributes attributes = MethodAttributes.Static |
                                                        MethodAttributes.HideBySig |
                                                        MethodAttributes.SpecialName |
                                                        MethodAttributes.RTSpecialName;

                    staticConstructor = new MethodDefinition(".cctor", attributes, type.Module.TypeSystem.Void);
                }

                var ilProcessor = staticConstructor.Body.GetILProcessor();

                staticConstructor.Body.Instructions.Add(Instruction.Create(OpCodes.Ldarg_0));

                StaticConstructorStagePrePostFragments stageFragments;

                if (StaticConstructorInitializerFragments.TryGetValue(
                        ConstructorStage.PropertyInitializationStage,
                        out stageFragments))
                {
                    GenerateFragments(stageFragments.InStageFragments, ilProcessor);
                    GenerateFragments(stageFragments.PostStageFragments, ilProcessor);
                }

                if (!constructorCreated)
                {
                    return;
                }

                staticConstructor.Body.Instructions.Add(Instruction.Create(OpCodes.Ret));

                type.Methods.Add(staticConstructor);
            }
            catch (Exception e)
            {
                Debug.Log(e.ToString());
                throw;
            }
        }