private static string GenerateNvimUIEventArgs( IEnumerable <NvimUIEvent> uiEvents) => string.Join("", uiEvents.Where(uiEvent => uiEvent.Parameters.Any()) .Select(uiEvent => { var eventName = StringUtil.ConvertToCamelCase(uiEvent.Name, true); return($@" public class {eventName}EventArgs : EventArgs {{ { string.Join("", uiEvent.Parameters.Select(param => { var type = NvimTypesMap.GetCSharpType(param.Type); var paramName = StringUtil.ConvertToCamelCase(param.Name, true); return $" public {type} {paramName} {{ get; set; }}\n"; })) } }}"); }));
/// <summary> /// Allows the types and attributes of plugin export parameters /// to be enumerated and simultaneously validated. /// </summary> /// <param name="typeVisitors"> /// A dictionary of handlers for the parameter types. /// </param> /// <param name="attributeVisitors"> /// A dictionary of handlers for the parameter attributes. /// </param> protected void VisitParameters( IReadOnlyDictionary <Type, Action <int> > typeVisitors, IReadOnlyDictionary <Type, Action <int, object> > attributeVisitors) { foreach (var param in Method.GetParameters() .Select((param, index) => new { Index = index, Type = param.ParameterType, Attributes = param.GetCustomAttributes() })) { var isValidAPIType = NvimTypesMap.IsValidType(param.Type); var isValidPluginType = typeVisitors.TryGetValue(param.Type, out var visitor); if (!isValidAPIType && !isValidPluginType) { throw new Exception( $"Plugin export has invalid parameter type \"{param.Type.Name}\""); } if (visitor != null // If there is not a visitor for the specific type, // try to use the "object" visitor as a default || typeVisitors.TryGetValue(typeof(object), out visitor)) { visitor(param.Index); } foreach (var attribute in param.Attributes) { if (attributeVisitors.TryGetValue(attribute.GetType(), out var attributeVisitor)) { attributeVisitor(param.Index, attribute); } } } }
private static string GenerateNvimUIEventCalls( IEnumerable <NvimUIEvent> uiEvents) => string.Join("", uiEvents.Select(uiEvent => { var camelCaseName = StringUtil.ConvertToCamelCase(uiEvent.Name, true); var eventArgs = uiEvent.Parameters.Any() ? $@"new {camelCaseName}EventArgs {{ { string.Join(",\n", uiEvent.Parameters.Select((param, index) => { var name = StringUtil.ConvertToCamelCase(param.Name, true); var type = NvimTypesMap.GetCSharpType(param.Type); return $@" {name} = ({type}) args[{index}]"; })) } }}" : "EventArgs.Empty"; return($@" case ""{uiEvent.Name}"": {camelCaseName}?.Invoke(this, {eventArgs}); break; "); }));
public void TestCSharpTypeConversion(string nvimType, string csharpType) { Assert.AreEqual(csharpType, NvimTypesMap.GetCSharpType(nvimType)); }
public void TestNvimTypeValidation(Type type, bool shouldBeValid) { Assert.AreEqual(shouldBeValid, NvimTypesMap.IsValidType(type)); }
private static string GenerateNvimMethods( IEnumerable <NvimFunction> functions, string prefixToRemove, bool isVirtualMethod) => string.Join("", functions.Select(function => { if (!function.Name.StartsWith(prefixToRemove)) { throw new Exception( $"Function {function.Name} does not " + $"have expected prefix \"{prefixToRemove}\""); } FunctionDoc doc = null; _functionDocs?.TryGetValue(function.Name, out doc); var camelCaseName = StringUtil.ConvertToCamelCase( function.Name.Substring(prefixToRemove.Length), true); var sendAccess = function.Method ? "_api." : string.Empty; var returnType = NvimTypesMap.GetCSharpType(function.ReturnType); var genericTypeParam = returnType == "void" ? string.Empty : $"<{returnType}>"; var parameters = (isVirtualMethod ? function.Parameters.Skip(1) : function.Parameters) .Select(param => new { param.Type, // Prefix every parameter name with the verbatim identifier `@` // to prevent them from being interpreted as keywords. // In the future, it might be worth considering adding a list // of all C# keywords and only adding the prefix to parameter // names that are in the list. Name = "@" + StringUtil.ConvertToCamelCase(param.Name, false) }).ToArray(); return($@"{string.Join(string.Empty, GetDocElement("summary", doc?.Summary).Concat( doc?.Parameters .Where(param => function.Parameters.Any(p => p.Name == param.Name) && (!isVirtualMethod || param.Name != function.Parameters.First().Name)) .SelectMany(param => GetDocElement("param", param.Description, $@"name=""{ StringUtil.ConvertToCamelCase(param.Name, false)}""")) ?? Enumerable.Empty<string>()).Concat( GetDocElement("returns", doc?.Return)).Concat( GetDocElement("remarks", doc?.Notes)).Select(docLine => $@" /// {docLine}"))} public Task{genericTypeParam} {camelCaseName}({string.Join(", ", parameters.Select(param => $"{NvimTypesMap.GetCSharpType(param.Type)} {param.Name}"))}) => {sendAccess}SendAndReceive{genericTypeParam}(new NvimRequest {{ Method = ""{function.Name}"", Arguments = GetRequestArguments( {string.Join(", ", (isVirtualMethod ? new[] {"_msgPackExtObj"} : Enumerable.Empty<string>()) .Concat(parameters.Select(param => param.Name)))}) }}); "); }));