public void Generate(List <PropertyTypeNode> root, List <string> usings = null)
        {
            if (root.Count == 0)
            {
                return;
            }

            _cache.Clear();

            // @TODO Cleanup

            var propertyNodesByName = root.Select(
                p => new KeyValuePair <string, PropertyTypeNode>(p.TypeName, p)
                ).ToDictionary(e => e.Key, e => e.Value);

            Func <string, CSharpGenerationCache.CodeInfo> dependancyLookupFunc = null;

            dependancyLookupFunc = (typeName) =>
            {
                // @TODO watch out for dependancy loops
                if (!propertyNodesByName.ContainsKey(typeName))
                {
                    throw new Exception($"Invalid request for property container type generation '{typeName}'");
                }

                if (_cache.Cache.ContainsKey(typeName))
                {
                    return(_cache.Cache[typeName]);
                }

                var g = new CSharpContainerGenerator();
                g.GeneratePropertyContainer(
                    propertyNodesByName[typeName],
                    dependancyLookupFunc);

                _cache.Cache[typeName] = new CSharpGenerationCache.CodeInfo()
                {
                    Code = g.Code.ToString(),
                    GeneratedPropertyFieldNames = g.PropertyBagItemNames
                };

                return(_cache.Cache[typeName]);
            };

            var code = new StringBuffer();

            WithUsing(code, usings);

            foreach (var container in root)
            {
                var g = new CSharpContainerGenerator();
                g.GeneratePropertyContainer(container, dependancyLookupFunc);

                code.Append(g.Code);
            }

            Code = code.ToString();
        }
예제 #2
0
        private void GeneratePropertyContainerFor(
            PropertyTypeNode c,
            Func <string, CSharpGenerationCache.CodeInfo> dependancyLookupFunc,
            StringBuffer gen)
        {
            var containerName = c.TypeName;

            var containerTypeTag = c.Tag;

            var baseClass = string.IsNullOrEmpty(c.OverrideDefaultBaseClass)
                ? "IPropertyContainer" : c.OverrideDefaultBaseClass;

            var rootScope = new Scope();

            var shouldGeneratePRopertyContainerImplementation = !c.NoDefaultImplementation;

            using (var d = new PropertyContainerDataTypeDecorator(c, rootScope.Code, new List <string> {
                baseClass
            }))
                using (var scope = new Scope(rootScope))
                {
                    if (shouldGeneratePRopertyContainerImplementation)
                    {
                        if (c.Properties.Count != 0)
                        {
                            foreach (var propertyType in c.Properties)
                            {
                                GenerateProperty(
                                    containerName,
                                    containerTypeTag,
                                    propertyType,
                                    scope
                                    );
                                scope.AddLine("");
                            }

                            scope.AddLine("");
                        }

                        GenerateUserHooksFor(c, scope);

                        // Add inherited properties if it applies

                        var propertyBagElementNames = PropertyBagItemNames;
                        if (!string.IsNullOrEmpty(c.OverrideDefaultBaseClass) && dependancyLookupFunc != null)
                        {
                            var cachedContainer = dependancyLookupFunc(c.OverrideDefaultBaseClass);
                            if (cachedContainer != null)
                            {
                                propertyBagElementNames = PropertyBagItemNames.Select(n => n).ToList();

                                propertyBagElementNames.AddRange(cachedContainer.GeneratedPropertyFieldNames);
                            }
                        }

                        GeneratePropertyBag(
                            c,
                            propertyBagElementNames,
                            scope);

                        GenerateConstructorFor(c, scope.Code);

                        GenerateStaticConstructorFor(c, scope.Code);

                        // @TODO Cleanup
                        // Recurse to collect nested container definitions

                        foreach (var nestedContainer in c.NestedContainers)
                        {
                            if (nestedContainer == null)
                            {
                                continue;
                            }

                            var g = new CSharpContainerGenerator()
                            {
                                DoGenerateNamespace = false
                            };
                            g.GeneratePropertyContainer(nestedContainer, dependancyLookupFunc);

                            if (!string.IsNullOrEmpty(g.Code.ToString()))
                            {
                                scope.AddLine(string.Empty);
                                scope.AddLine(string.Empty);

                                scope.AddLine(g.Code.ToString());

                                scope.AddLine(string.Empty);
                                scope.AddLine(string.Empty);
                            }
                        }

                        scope.AddLine("public IVersionStorage VersionStorage => DefaultVersionStorage.Instance;");
                        scope.AddLine(Environment.NewLine);
                    }
                }

            gen.Append(rootScope.Code);
        }