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(); }
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); }