public static Task SaveSnippets(string directory, CancellationToken ct) { var groups = GuardFunctionAttribute.GetMethods(Assembly.GetAssembly(typeof(Guard))) .Where(p => p.Value.Shortcut != null) .GroupBy(p => p.Value.Shortcut) .ToList(); return(SaveVisualStudioSnippets("guard-cs.vs.snippet")); async Task SaveVisualStudioSnippets(string name) { var snippets = groups.SelectMany(g => g.SelectMany(p => VisualStudioSnippet.CreateSnippets(p.Key, p.Value))); var document = VisualStudioSnippet.CreateDocument(snippets); using (var file = File.Create(Path.Combine(directory, name))) using (var writer = new StreamWriter(file, Encoding)) { await document.SaveAsync(writer, SaveOptions.None, ct).ConfigureAwait(false); Console.WriteLine($"Created \"{file.Name}\""); } } }
public void GuardFunctionInit() { Assert.Throws <ArgumentNullException>("group", () => new GuardFunctionAttribute(null)); Assert.Throws <ArgumentException>("group", () => new GuardFunctionAttribute(string.Empty)); Assert.Throws <ArgumentException>("group", () => new GuardFunctionAttribute(" ")); var attr = new GuardFunctionAttribute("G"); Assert.Equal("G", attr.Group); Assert.Null(attr.Shortcut); Assert.Equal(0, attr.Order); Assert.Throws <ArgumentException>("shortcut", () => new GuardFunctionAttribute("G", string.Empty)); Assert.Throws <ArgumentException>("shortcut", () => new GuardFunctionAttribute("G", " ")); Assert.Throws <ArgumentException>("shortcut", () => new GuardFunctionAttribute("G", "s")); Assert.Throws <ArgumentException>("shortcut", () => new GuardFunctionAttribute("G", "g")); attr = new GuardFunctionAttribute("G", "gs"); Assert.Equal("G", attr.Group); Assert.Equal("gs", attr.Shortcut); Assert.Equal(0, attr.Order); attr = new GuardFunctionAttribute("G", order: 1); Assert.Equal("G", attr.Group); Assert.Null(attr.Shortcut); Assert.Equal(1, attr.Order); attr = new GuardFunctionAttribute("G", "gs", order: 1); Assert.Equal("G", attr.Group); Assert.Equal("gs", attr.Shortcut); Assert.Equal(1, attr.Order); }
public static IEnumerable <VisualStudioSnippet> CreateSnippets(MethodInfo method, GuardFunctionAttribute attribute) { var isExtMethod = method.GetCustomAttribute <ExtensionAttribute>() != null; var isStateGuard = attribute.Group.Equals("State", StringComparison.OrdinalIgnoreCase); var typeParams = method.IsGenericMethod ? method.GetGenericArguments() : Array.Empty <Type>(); var allParams = method.GetParameters(); var listParams = allParams .Skip(isExtMethod ? 1 : 0) .Where(p => p.Name != "message" && p.GetCustomAttribute <CallerMemberNameAttribute>() is null) .ToList(); var element = CreateElement(attribute.Shortcut, false); yield return(new VisualStudioSnippet(method, attribute, attribute.Shortcut, element)); if (isStateGuard || method.Name == nameof(Guard.Argument) || method.Name == nameof(Guard.Null) || method.Name == nameof(Guard.NotNull)) { yield break; } var canBeNull = !isExtMethod; if (!canBeNull) { var constraints = method.GetGenericArguments().FirstOrDefault()?.GetGenericParameterConstraints(); if (constraints != null) { canBeNull = !constraints.Contains(typeof(ValueType)); if (!canBeNull) { var argumentType = allParams[0].ParameterType.GetGenericArguments()[0]; canBeNull = argumentType.IsGenericType && argumentType.GetGenericTypeDefinition() == typeof(Nullable <>); } } else { var argumentType = allParams[0].ParameterType.GetGenericArguments()[0]; canBeNull = !argumentType.IsValueType; if (!canBeNull && argumentType.IsGenericType && argumentType.GetGenericTypeDefinition() == typeof(Nullable <>)) { canBeNull = true; } } } if (canBeNull) { var shortcut = attribute.Shortcut.Insert(1, "x"); element = CreateElement(shortcut, true); yield return(new VisualStudioSnippet(method, attribute, shortcut, element)); } XElement CreateElement(string shortcut, bool addNullGuard) { var title = string.Format( "{0}{1}.{2}{3}({4})", method.DeclaringType.Name, addNullGuard ? ".NotNull()" : string.Empty, method.Name, !isExtMethod && typeParams.Length > 0 ? $"`{typeParams.Length}" : string.Empty, listParams.Count > 0 ? string.Join(", ", listParams.Select(p => p.Name.Replace("&", string.Empty))) : string.Empty); var code = new StringBuilder("Guard"); if (!isStateGuard) { code.Append(".Argument($arg$, nameof($arg$))"); } if (method.Name == nameof(Guard.Argument)) { code.Append("$end$"); } else { if (addNullGuard) { code.Append(".NotNull()"); } code.AppendFormat(".{0}", method.Name); if (!isExtMethod && typeParams.Length > 0) { code.AppendFormat("<{0}>", string.Join(", ", typeParams.Select(t => $"${t.Name}$"))); } code.Append("("); code.Append(string.Join(", ", listParams.Select(p => { if (p.ParameterType == typeof(StringComparison)) { return($"StringComparison.${p.Name}$"); } else if (p.ParameterType == typeof(StringComparer)) { return($"StringComparer.${p.Name}$"); } return($"${p.Name}$"); }))); code.AppendFormat(")$end$;"); } return(new XElement( Namespace + "CodeSnippet", new XAttribute("Format", "1.0.0"), new XElement( Namespace + "Header", new XElement(Namespace + "Title", title), new XElement(Namespace + "Shortcut", shortcut)), new XElement( Namespace + "Snippet", new XElement( Namespace + "Imports", new XElement( Namespace + "Import", new XElement(Namespace + "Namespace", nameof(Dawn)))), new XElement( Namespace + "Declarations", isStateGuard ? null : new XElement( Namespace + "Literal", new XElement(Namespace + "ID", "arg"), new XElement(Namespace + "Default", "arg")), isExtMethod ? null : typeParams.Select(t => new XElement( Namespace + "Literal", new XElement(Namespace + "ID", t.Name), new XElement(Namespace + "Default", t.Name))), listParams.Select(p => new XElement( Namespace + "Literal", new XElement(Namespace + "ID", p.Name), new XElement(Namespace + "Default", p.Name)))), new XElement( Namespace + "Code", new XAttribute("Language", "csharp"), new XCData(code.ToString()))))); } }
private VisualStudioSnippet( MethodInfo method, GuardFunctionAttribute attribute, string shortcut, XElement element) : base(method, attribute, shortcut) => _element = element;
public Snippet(MethodInfo method, GuardFunctionAttribute attribute, string shortcut) { Method = method; Attribute = attribute; Shortcut = shortcut; }
private static IEnumerable <KeyValuePair <MethodInfo, GuardFunctionAttribute> > GetMarkedMethods() => GuardFunctionAttribute.GetMethods(Assembly.GetAssembly(typeof(Guard)));