static void Generate(string apiPath) { try { // Enumerate through all *.json files in the provided path and generate classes if (Directory.Exists(apiPath)) { Log("Scanning {0}...", apiPath); var jsonFiles = Directory.EnumerateFiles(apiPath, "*.json").ToList(); Log("Found {0} objects.", jsonFiles.Count); if (jsonFiles.Count > 0) { // Parse JSON into metadata classes var generatedPath = Path.Combine(apiPath, "generated"); if (!Directory.Exists(generatedPath)) Directory.CreateDirectory(generatedPath); Log("Parsing JSON files..."); var metaClasses = new List<MetaClass>(); foreach (var jsonFile in jsonFiles) { Log("Parsing {0}...", Path.GetFileName(jsonFile)); var node = JsonConvert.DeserializeObject<Node>(File.ReadAllText(jsonFile)); if (node.Attributes != null) { var metaClass = new MetaClass(node); if (!String.IsNullOrWhiteSpace(metaClass.Name)) { metaClasses.Add(metaClass); } } } // Generate classes from the metadata Log("Generating classes..."); foreach (var metaClass in metaClasses) { Log("Generating {0}...", metaClass.FullName); // Add properties from mixins to the classes metaClass.AddMixins(metaClasses); // Add class interfaces metaClass.AddInterfaces(metaClasses); // Generate class/interface from T4 template string content = null; if (!metaClass.IsInterface) { var template = new ClassTemplate { Session = new Dictionary<string, object> { { "Model", metaClass } } }; content = template.TransformText(); } else if (metaClass.IsInterface) { var template = new InterfaceTemplate { Session = new Dictionary<string, object> { { "Model", metaClass } } }; content = template.TransformText(); } // Write output class to .cs file if (content != null) { var relOutputFile = metaClass.OriginalFullName.Replace(".", @"\") + ".cs"; if (!relOutputFile.StartsWith(@"qx\")) relOutputFile = @"qx\" + relOutputFile; var outputFile = Path.Combine(generatedPath, relOutputFile); var outputPath = Path.GetDirectoryName(outputFile); if (!Directory.Exists(outputPath)) Directory.CreateDirectory(outputPath); File.WriteAllText(outputFile, content); } } } Log("Generation completed."); } else { Log("Path not found: " + apiPath); } } catch (Exception e) { Log(e); } }
public MetaMethod(Node node, MetaClass metaClass) : base(node) { IsConstructor = node.Attributes.ContainsKey("isCtor") && node.GetAttributeValue("isCtor") == "True"; if (IsConstructor) { Name = metaClass.Name; FormattedName = Name; ReturnType = ""; } else { FormattedName = StringUtils.CapitalizeFirstLetter(FormattedName.Replace("$", "")); } IsStatic = node.Attributes.ContainsKey("isStatic") && node.GetAttributeValue("isStatic") == "True"; AccessType = node.GetAttributeValue("access"); if (AccessType == null) AccessType = "public"; Parameters = new List<MetaMethodParameter>(); var paramsNode = node.GetChildByType(NodeType.Params); if (paramsNode != null) { foreach (var el in paramsNode.Children) { Parameters.Add(new MetaMethodParameter(el)); } } // Make all parameters following the optional ones to also be optional (not always the case) bool hasOptional = false; foreach (var parameter in Parameters) { if (parameter.DefaultValue != null) { hasOptional = true; } else if (hasOptional) { parameter.DefaultValue = "null"; parameter.FormatDefaultValue(); } } // Get the return / parameter type from the relevant property (if there is one) var fromProperty = node.GetAttributeValue("fromProperty"); if (fromProperty != null) { var property = metaClass.Properties.FirstOrDefault(p => p.Name == fromProperty); if (property != null) { if (Name.StartsWith("get")) { ReturnType = property.Type; } else if (Name.StartsWith("set")) { Parameters[0].Type = property.Type; } } } // Get return type from the metadata if (ReturnType == null && fromProperty == null) { var returnNode = node.GetChildByType(NodeType.Return); if (returnNode != null) { var typesNode = returnNode.GetChildByType(NodeType.Types); if (typesNode != null) { // There could be more than one return type, in which case make it an object if (typesNode.Children.Count == 1) { ReturnType = typesNode.Children[0].GetAttributeValue("type"); } else { // If only one of the return types is non-null, set it as a return type // otherwise set the return type to object var nonNullTypes = new List<string>(); foreach (var typeNode in typesNode.Children) { var type = typeNode.GetAttributeValue("type"); if (type != "null") { nonNullTypes.Add(type); } } if (nonNullTypes.Count == 1) { ReturnType = nonNullTypes[0]; } else { ReturnType = "object"; } } } var commentNode = returnNode.GetChildByType(NodeType.Desc); if (commentNode != null) { ReturnComment = commentNode.GetAttributeValue("text"); } } } if (ReturnType == "null") ReturnType = "object"; if (!IsConstructor) { if (ReturnType == null) ReturnType = "void"; else ReturnType = TypeMapper.MapType(ReturnType); } }