1 #region Copyright & License Information
2 /*
3  * Copyright 2007-2020 The OpenRA Developers (see AUTHORS)
4  * This file is part of OpenRA, which is free software. It is made
5  * available to you under the terms of the GNU General Public License
6  * as published by the Free Software Foundation, either version 3 of
7  * the License, or (at your option) any later version. For more
8  * information, see COPYING.
9  */
10 #endregion
11 
12 using System;
13 using System.Linq;
14 using System.Reflection;
15 using OpenRA.Scripting;
16 
17 namespace OpenRA.Mods.Common.UtilityCommands
18 {
19 	// See https://studio.zerobrane.com/doc-api-auto-complete for reference
20 	class ExtractZeroBraneStudioLuaAPI : IUtilityCommand
21 	{
22 		string IUtilityCommand.Name { get { return "--zbstudio-lua-api"; } }
23 
IUtilityCommand.ValidateArguments(string[] args)24 		bool IUtilityCommand.ValidateArguments(string[] args)
25 		{
26 			return true;
27 		}
28 
29 		[Desc("Generate ZeroBrane Studio Lua API and auto-complete descriptions.")]
IUtilityCommand.Run(Utility utility, string[] args)30 		void IUtilityCommand.Run(Utility utility, string[] args)
31 		{
32 			// HACK: The engine code assumes that Game.modData is set.
33 			Game.ModData = utility.ModData;
34 
35 			Console.WriteLine("local interpreter = {");
36 			Console.WriteLine("  name = \"OpenRA\",");
37 			Console.WriteLine("  description = \"OpenRA map scripting Lua API\",");
38 			Console.WriteLine("  api = {\"baselib\", \"openra\"},");
39 			Console.WriteLine("  hasdebugger = false,");
40 			Console.WriteLine("  skipcompile = true,");
41 			Console.WriteLine("}");
42 			Console.WriteLine();
43 
44 			Console.WriteLine("-- This is an automatically generated Lua API definition generated for {0} of OpenRA.", Game.ModData.Manifest.Metadata.Version);
45 			Console.WriteLine("-- https://github.com/OpenRA/OpenRA/wiki/Utility was used with the --zbstudio-lua-api parameter.");
46 			Console.WriteLine("-- See https://github.com/OpenRA/OpenRA/wiki/Lua-API for human readable documentation.");
47 			Console.WriteLine();
48 			Console.WriteLine("local api = {");
49 
50 			var tables = Game.ModData.ObjectCreator.GetTypesImplementing<ScriptGlobal>().OrderBy(t => t.Name);
51 			foreach (var t in tables)
52 			{
53 				var name = t.GetCustomAttributes<ScriptGlobalAttribute>(true).First().Name;
54 				Console.WriteLine("  " + name + " = {");
55 				Console.WriteLine("    type = \"class\",");
56 				Console.WriteLine("    childs = {");
57 
58 				var members = ScriptMemberWrapper.WrappableMembers(t);
59 				foreach (var member in members.OrderBy(m => m.Name))
60 				{
61 					Console.WriteLine("      " + member.Name + " = {");
62 					var methodInfo = member as MethodInfo;
63 					if (methodInfo != null)
64 						Console.WriteLine("        type = \"function\",");
65 
66 					var propertyInfo = member as PropertyInfo;
67 					if (propertyInfo != null)
68 						Console.WriteLine("        type = \"value\",");
69 
70 					if (member.HasAttribute<DescAttribute>())
71 					{
72 						var desc = member.GetCustomAttributes<DescAttribute>(true).First().Lines.JoinWith("\n");
73 						Console.WriteLine("        description = [[{0}]],", desc);
74 					}
75 
76 					if (methodInfo != null)
77 					{
78 						var parameters = methodInfo.GetParameters().Select(pi => pi.LuaDocString());
79 						Console.WriteLine("        args = \"({0})\",", parameters.JoinWith(", "));
80 
81 						var returnType = methodInfo.ReturnType.LuaDocString();
82 						Console.WriteLine("        returns = \"({0})\",", returnType);
83 					}
84 
85 					Console.WriteLine("      },");
86 				}
87 
88 				Console.WriteLine("    }");
89 				Console.WriteLine("  },");
90 			}
91 
92 			var actorProperties = Game.ModData.ObjectCreator.GetTypesImplementing<ScriptActorProperties>().SelectMany(cg =>
93 			{
94 				return ScriptMemberWrapper.WrappableMembers(cg);
95 			});
96 
97 			var scriptProperties = Game.ModData.ObjectCreator.GetTypesImplementing<ScriptPlayerProperties>().SelectMany(cg =>
98 			{
99 				return ScriptMemberWrapper.WrappableMembers(cg);
100 			});
101 
102 			var properties = actorProperties.Concat(scriptProperties);
103 			foreach (var property in properties.OrderBy(m => m.Name))
104 			{
105 				Console.WriteLine("  " + property.Name + " = {");
106 
107 				var methodInfo = property as MethodInfo;
108 				if (methodInfo != null)
109 					Console.WriteLine("    type = \"function\",");
110 
111 				var propertyInfo = property as PropertyInfo;
112 				if (propertyInfo != null)
113 					Console.WriteLine("    type = \"value\",");
114 
115 				if (property.HasAttribute<DescAttribute>())
116 				{
117 					var desc = property.GetCustomAttributes<DescAttribute>(true).First().Lines.JoinWith("\n");
118 					Console.WriteLine("    description = [[{0}]],", desc);
119 				}
120 
121 				if (methodInfo != null)
122 				{
123 					var parameters = methodInfo.GetParameters().Select(pi => pi.LuaDocString());
124 					Console.WriteLine("    args = \"({0})\",", parameters.JoinWith(", "));
125 
126 					var returnType = methodInfo.ReturnType.LuaDocString();
127 					Console.WriteLine("    returns = \"({0})\",", returnType);
128 				}
129 
130 				Console.WriteLine("  },");
131 			}
132 
133 			Console.WriteLine("}");
134 			Console.WriteLine();
135 			Console.WriteLine("return {");
136 			Console.WriteLine("  name = \"OpenRA\",");
137 			Console.WriteLine("  description = \"Adds API description for auto-complete and tooltip support for OpenRA.\",");
138 			Console.WriteLine("  author = \"Matthias Mailänder\",");
139 			Console.WriteLine("  version = \"{0}\",".F(Game.ModData.Manifest.Metadata.Version.Split('-').LastOrDefault()));
140 			Console.WriteLine();
141 			Console.WriteLine("  onRegister = function(self)");
142 			Console.WriteLine("    ide:AddAPI(\"lua\", \"openra\", api)");
143 			Console.WriteLine("    ide:AddInterpreter(\"openra\", interpreter)");
144 			Console.WriteLine("  end,");
145 			Console.WriteLine();
146 			Console.WriteLine("  onUnRegister = function(self)");
147 			Console.WriteLine("    ide:RemoveAPI(\"lua\", \"openra\")");
148 			Console.WriteLine("    ide:RemoveInterpreter(\"openra\")");
149 			Console.WriteLine("  end,");
150 			Console.WriteLine("}");
151 		}
152 	}
153 }
154