From 4a7f09b20a916f6f38ed4cef8a957ef2adb27622 Mon Sep 17 00:00:00 2001 From: Malware Date: Sun, 22 Jul 2018 15:31:33 +0200 Subject: [PATCH] Further work on the API documentation stuff Version update --- Source/DocGen/ApiEntry.cs | 245 ++++++++++++++++++ Source/DocGen/DocGen.csproj | 1 + Source/DocGen/ProgrammableBlockApi.cs | 107 ++++---- Source/DocGen/Whitelist.cs | 4 +- Source/DocGen/WhitelistKey.cs | 134 +--------- Source/MDK/MDKPackage.GeneratedInfo.cs | 4 +- Source/MDK/other.xml | 2 +- Source/MDK/source.extension.vsixmanifest | 2 +- .../ProjectScriptInfo.GeneratedInfo.cs | 2 +- 9 files changed, 316 insertions(+), 185 deletions(-) create mode 100644 Source/DocGen/ApiEntry.cs diff --git a/Source/DocGen/ApiEntry.cs b/Source/DocGen/ApiEntry.cs new file mode 100644 index 0000000..58eafd7 --- /dev/null +++ b/Source/DocGen/ApiEntry.cs @@ -0,0 +1,245 @@ +using System; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.Linq; +using System.Reflection; +using System.Xml.Linq; + +namespace DocGen +{ + class ApiEntry + { + public static ApiEntry Create(MemberInfo memberInfo, XDocument documentation) + { + switch (memberInfo) + { + case Type type: + return ForType(type); + case ConstructorInfo constructorInfo: + return ForConstructor(constructorInfo); + case EventInfo eventInfo: + return ForEvent(eventInfo); + case FieldInfo fieldInfo: + return ForField(fieldInfo); + case PropertyInfo propertyInfo: + return ForProperty(propertyInfo); + case MethodInfo methodInfo: + return ForMethod(methodInfo); + default: + return null; + } + } + + static ApiEntry ForType(Type type) + { + if (!type.IsPublic && !type.IsNestedPublic && !type.IsNestedFamily && !type.IsNestedFamANDAssem && !type.IsNestedFamORAssem) + return null; + if (type.IsGenericTypeDefinition || type.IsGenericType) + return ForGenericType(type); + + var assemblyName = type.Assembly.GetName().Name; + var namespaceName = type.Namespace; + var name = type.Name; + var whitelistKey = $"{namespaceName}.{name}"; + var xmlDocKey = $"T:{namespaceName}.{name}"; + return new ApiEntry(type, assemblyName, namespaceName, name, name, whitelistKey, xmlDocKey); + } + + static ApiEntry ForGenericType(Type type) + { + var assemblyName = type.Assembly.GetName().Name; + var namespaceName = type.IsGenericType ? type.GetGenericTypeDefinition().Namespace : type.Namespace; + var name = type.IsGenericType ? type.GetGenericTypeDefinition().Name : type.Name; + var separatorIndex = name.IndexOf('`'); + if (separatorIndex >= 0) + name = name.Substring(0, separatorIndex); + var signature = name; + var genericArguments = type.GetGenericArguments(); + var whitelistKey = $"{namespaceName}.{name}"; + var xmlDocKey = $"T:{whitelistKey}"; + signature += "<" + string.Join(", ", genericArguments.Select(arg => arg.IsGenericParameter ? arg.Name : arg.FullName)) + ">"; + whitelistKey += "<" + string.Join(", ", genericArguments.Select(arg => arg.IsGenericParameter ? arg.Name : arg.FullName)) + ">"; + xmlDocKey += "{" + string.Join(", ", genericArguments.Select(arg => arg.IsGenericParameter ? arg.Name : arg.FullName)) + "}"; + return new ApiEntry(type, assemblyName, namespaceName, name, signature, whitelistKey, xmlDocKey); + } + + static ApiEntry ForConstructor(ConstructorInfo constructorInfo) + { + if (constructorInfo.IsSpecialName || !constructorInfo.IsPublic && !constructorInfo.IsFamily && !constructorInfo.IsFamilyAndAssembly && !constructorInfo.IsFamilyOrAssembly) + return null; + var basis = ForType(constructorInfo.DeclaringType); + var signature = constructorInfo.Name; + var whitelistKey = $"{basis.WhitelistKey}.{constructorInfo.Name}"; + var xmlDocKey = "C" + basis.XmlDocKey.Substring(1); + var parameters = constructorInfo.GetParameters(); + signature += "(" + string.Join(", ", parameters.Select(SignatureParameterStr)) + ")"; + whitelistKey += "(" + string.Join(", ", parameters.Select(WhitelistParameterStr)) + ")"; + xmlDocKey += "(" + string.Join(", ", parameters.Select(XmlDocParameterStr)) + ")"; + return new ApiEntry(constructorInfo, basis.AssemblyName, basis.NamespaceName, constructorInfo.Name, signature, whitelistKey, xmlDocKey); + } + + static ApiEntry ForEvent(EventInfo eventInfo) + { + if (eventInfo.IsSpecialName || !(eventInfo.AddMethod?.IsPublic ?? false) && !(eventInfo.AddMethod?.IsFamily ?? false) && !(eventInfo.AddMethod?.IsFamilyAndAssembly ?? false) && !(eventInfo.AddMethod?.IsFamilyOrAssembly ?? false) + && !(eventInfo.RemoveMethod?.IsPublic ?? false) && !(eventInfo.RemoveMethod?.IsFamily ?? false) && !(eventInfo.RemoveMethod?.IsFamilyAndAssembly ?? false) && !(eventInfo.RemoveMethod?.IsFamilyOrAssembly ?? false)) + return null; + var basis = ForType(eventInfo.DeclaringType); + var whitelistKey = $"{basis.WhitelistKey}.{eventInfo.Name}"; + var xmlDocKey = "E" + basis.XmlDocKey.Substring(1); + return new ApiEntry(eventInfo, basis.AssemblyName, basis.NamespaceName, eventInfo.Name, eventInfo.Name, whitelistKey, xmlDocKey); + } + + static ApiEntry ForField(FieldInfo fieldInfo) + { + if (fieldInfo.IsSpecialName || !fieldInfo.IsPublic && !fieldInfo.IsFamily && !fieldInfo.IsFamilyAndAssembly && !fieldInfo.IsFamilyOrAssembly) + return null; + var basis = ForType(fieldInfo.DeclaringType); + var whitelistKey = $"{basis.WhitelistKey}.{fieldInfo.Name}"; + var xmlDocKey = "F" + basis.XmlDocKey.Substring(1); + var signature = $"{ForType(fieldInfo.FieldType).Signature} {fieldInfo.Name}"; + return new ApiEntry(fieldInfo, basis.AssemblyName, basis.NamespaceName, fieldInfo.Name, signature, whitelistKey, xmlDocKey); + } + + static ApiEntry ForProperty(PropertyInfo propertyInfo) + { + if (propertyInfo.IsSpecialName || !(propertyInfo.GetMethod?.IsPublic ?? false) && !(propertyInfo.GetMethod?.IsFamily ?? false) && !(propertyInfo.GetMethod?.IsFamilyAndAssembly ?? false) && !(propertyInfo.GetMethod?.IsFamilyOrAssembly ?? false) + && !(propertyInfo.SetMethod?.IsPublic ?? false) && !(propertyInfo.SetMethod?.IsFamily ?? false) && !(propertyInfo.SetMethod?.IsFamilyAndAssembly ?? false) && !(propertyInfo.SetMethod?.IsFamilyOrAssembly ?? false)) + return null; + var basis = ForType(propertyInfo.DeclaringType); + var whitelistKey = $"{basis.WhitelistKey}.{propertyInfo.Name}"; + var xmlDocKey = "P" + basis.XmlDocKey.Substring(1); + var signature = $"{ForType(propertyInfo.PropertyType).Signature} {propertyInfo.Name}"; + return new ApiEntry(propertyInfo, basis.AssemblyName, basis.NamespaceName, propertyInfo.Name, signature, whitelistKey, xmlDocKey); + } + + static ApiEntry ForMethod(MethodInfo methodInfo) + { + if (methodInfo.IsSpecialName || !methodInfo.IsPublic && !methodInfo.IsFamily && !methodInfo.IsFamilyAndAssembly && !methodInfo.IsFamilyOrAssembly) + return null; + + if (methodInfo.IsGenericMethodDefinition || methodInfo.IsGenericMethod) + return ForGenericMethod(methodInfo); + var basis = ForType(methodInfo.DeclaringType); + var signature = methodInfo.Name; + var whitelistKey = $"{basis.WhitelistKey}.{methodInfo.Name}"; + var xmlDocKey = "M" + basis.XmlDocKey.Substring(1); + + var parameters = methodInfo.GetParameters(); + signature += "(" + string.Join(", ", parameters.Select(SignatureParameterStr)) + ")"; + whitelistKey += "(" + string.Join(", ", parameters.Select(WhitelistParameterStr)) + ")"; + xmlDocKey += "(" + string.Join(", ", parameters.Select(XmlDocParameterStr)) + ")"; + + if (methodInfo.ReturnType == typeof(void)) + signature = $"void {signature}"; + else + signature = $"{ForType(methodInfo.ReturnType)?.Signature} {signature}"; + return new ApiEntry(methodInfo, basis.AssemblyName, basis.NamespaceName, methodInfo.Name, signature, whitelistKey, xmlDocKey); + } + + static ApiEntry ForGenericMethod(MethodInfo methodInfo) + { + var basis = ForType(methodInfo.DeclaringType); + var name = methodInfo.Name; + var separatorIndex = name.IndexOf('`'); + if (separatorIndex >= 0) + name = name.Substring(0, separatorIndex); + var signature = name; + var whitelistKey = $"{basis.WhitelistKey}.{methodInfo.Name}"; + var xmlDocKey = "M" + basis.XmlDocKey.Substring(1); + var genericArguments = methodInfo.GetGenericArguments(); + signature += "<" + string.Join(", ", genericArguments.Select(arg => arg.Name)) + ">"; + whitelistKey += "<" + string.Join(", ", genericArguments.Select(arg => arg.Name)) + ">"; + xmlDocKey += "{" + string.Join(", ", genericArguments.Select(arg => arg.Name)) + "}"; + var parameters = methodInfo.GetParameters(); + signature += "(" + string.Join(", ", parameters.Select(SignatureParameterStr)) + ")"; + whitelistKey += "(" + string.Join(", ", parameters.Select(WhitelistParameterStr)) + ")"; + xmlDocKey += "(" + string.Join(", ", parameters.Select(XmlDocParameterStr)) + ")"; + + if (methodInfo.ReturnType == typeof(void)) + signature = $"void {signature}"; + else + signature = $"{ForType(methodInfo.ReturnType).Signature} {signature}"; + return new ApiEntry(methodInfo, basis.AssemblyName, basis.NamespaceName, name, signature, whitelistKey, xmlDocKey); + } + + static string SignatureParameterStr(ParameterInfo parameterInfo) + { + var prefix = parameterInfo.ParameterType.IsByRef ? "ref " : parameterInfo.ParameterType.IsPointer ? "*" : parameterInfo.IsOut ? "out " : ""; + var type = parameterInfo.ParameterType.IsByRef || parameterInfo.ParameterType.IsPointer ? parameterInfo.ParameterType.GetElementType() : parameterInfo.ParameterType; + return prefix + ForType(type).Signature; + } + + static string WhitelistParameterStr(ParameterInfo parameterInfo) + { + var prefix = parameterInfo.ParameterType.IsByRef ? "ref " : parameterInfo.ParameterType.IsPointer ? "*" : parameterInfo.IsOut ? "out " : ""; + var type = parameterInfo.ParameterType.IsByRef || parameterInfo.ParameterType.IsPointer ? parameterInfo.ParameterType.GetElementType() : parameterInfo.ParameterType; + return prefix + ForType(type).WhitelistKey; + } + + static string XmlDocParameterStr(ParameterInfo parameterInfo) + { + var prefix = parameterInfo.ParameterType.IsByRef ? "ref " : parameterInfo.ParameterType.IsPointer ? "*" : parameterInfo.IsOut ? "out " : ""; + var type = parameterInfo.ParameterType.IsByRef || parameterInfo.ParameterType.IsPointer ? parameterInfo.ParameterType.GetElementType() : parameterInfo.ParameterType; + return prefix + ForType(type).XmlDocKey.Substring(2); + } + + public ApiEntry(MemberInfo member, string assemblyName, string namespaceName, string name, string signature, string whitelistKey, string xmlDocKey) + { + Member = member; + AssemblyName = assemblyName; + NamespaceName = namespaceName; + Name = name; + Signature = signature; + WhitelistKey = whitelistKey; + XmlDocKey = xmlDocKey; + FullName = $"{NamespaceName}.{name}"; + + InheritedEntries = new ReadOnlyCollection(_inheritedEntries); + InheritorEntries = new ReadOnlyCollection(_inheritorEntries); + MemberEntries = new ReadOnlyCollection(_memberEntries); + } + + List _inheritedEntries = new List(); + List _inheritorEntries = new List(); + List _memberEntries = new List(); + + public MemberInfo Member { get; } + public ApiEntry DeclaringEntry { get; private set; } + public ReadOnlyCollection MemberEntries { get; } + public ReadOnlyCollection InheritedEntries { get; } + public ReadOnlyCollection InheritorEntries { get; } + public string AssemblyName { get; } + public string NamespaceName { get; } + public string Name { get; } + public string Signature { get; } + public string FullName { get; } + public string WhitelistKey { get; } + public string XmlDocKey { get; } + + public void ResolveLinks(List entries) + { + DeclaringEntry = entries.FirstOrDefault(e => e.Member == Member.DeclaringType); + DeclaringEntry?._memberEntries.Add(this); + if (Member is Type type) + { + var entry = entries.FirstOrDefault(e => e.Member == type.BaseType); + if (entry != null) + { + _inheritedEntries.Add(entry); + entry._inheritorEntries.Add(this); + } + + var interfaces = type.GetInterfaces(); + foreach (var interfaceType in interfaces) + { + entry = entries.FirstOrDefault(e => e.Member == interfaceType); + if (entry != null) + { + _inheritedEntries.Add(entry); + entry._inheritorEntries.Add(this); + } + } + } + } + } +} \ No newline at end of file diff --git a/Source/DocGen/DocGen.csproj b/Source/DocGen/DocGen.csproj index ba2ef1d..5df0e1b 100644 --- a/Source/DocGen/DocGen.csproj +++ b/Source/DocGen/DocGen.csproj @@ -44,6 +44,7 @@ + diff --git a/Source/DocGen/ProgrammableBlockApi.cs b/Source/DocGen/ProgrammableBlockApi.cs index 3641ae1..e7ed11c 100644 --- a/Source/DocGen/ProgrammableBlockApi.cs +++ b/Source/DocGen/ProgrammableBlockApi.cs @@ -8,7 +8,6 @@ using System.Text.RegularExpressions; using System.Threading.Tasks; using System.Xml.Linq; -using System.Xml.XPath; using Malware.MDKUtilities; namespace DocGen @@ -16,8 +15,8 @@ namespace DocGen class ProgrammableBlockApi { List _members = new List(); - List _assemblies; - List>> _groupings; + List _entries = new List(); + readonly HashSet _invalidCharacters = new HashSet(Path.GetInvalidFileNameChars()); public async Task Scan(string whitelistCacheFileName) { @@ -33,8 +32,29 @@ await Task.Run(() => foreach (var dllFile in dllFiles) Visit(whitelist, dllFile); - _groupings = _members.GroupBy(m => m.DeclaringType).GroupBy(m => m.Key.Assembly) - .ToList(); + foreach (var assemblyGroup in _members.GroupBy(m => m.DeclaringType.Assembly)) + { + var assemblyPath = new Uri(assemblyGroup.Key.CodeBase).LocalPath; + var xmlFileName = Path.ChangeExtension(assemblyPath, "xml"); + XDocument documentation; + if (File.Exists(xmlFileName)) + documentation = XDocument.Load(xmlFileName); + else + documentation = null; + foreach (var typeGroup in assemblyGroup.GroupBy(m => m.DeclaringType)) + { + var typeEntry = ApiEntry.Create(typeGroup.Key, documentation); + _entries.Add(typeEntry); + foreach (var member in typeGroup) + { + var entry = ApiEntry.Create(member, documentation); + _entries.Add(entry); + } + } + } + + foreach (var entry in _entries) + entry.ResolveLinks(_entries); }); } @@ -93,30 +113,20 @@ public async Task SaveAsync(string path) await file.WriteLineAsync("#Index"); await file.WriteLineAsync(); - foreach (var assemblyGroup in _groupings.OrderBy(g => g.Key.GetName().Name)) + foreach (var assemblyGroup in _entries.GroupBy(e => e.AssemblyName).OrderBy(e => e.Key)) { - var assemblyPath = new Uri(assemblyGroup.Key.CodeBase).LocalPath; - var assemblyFileName = Path.GetFileName(assemblyPath); - var xmlFileName = Path.ChangeExtension(assemblyPath, "xml"); - XDocument documentation; - if (File.Exists(xmlFileName)) - documentation = XDocument.Load(xmlFileName); - else - documentation = null; - - await file.WriteLineAsync($"##{assemblyFileName}"); - foreach (var typeGroup in assemblyGroup.OrderBy(g => g.Key.FullName)) + await file.WriteLineAsync($"##{assemblyGroup.Key}"); + foreach (var typeGroup in assemblyGroup.GroupBy(e => e.DeclaringEntry ?? e).OrderBy(g => g.Key.FullName)) { - var typeKey = WhitelistKey.ForType(typeGroup.Key); - var mdPath = ToMdFileName(typeKey.Path); - await file.WriteLineAsync($"**[`{typeKey.Path}`]({mdPath})**"); + var mdPath = ToMdFileName(typeGroup.Key.FullName); + await file.WriteLineAsync($"**[`{typeGroup.Key.Signature}`]({mdPath})**"); foreach (var member in typeGroup.OrderBy(m => m.Name)) { - var memberKey = WhitelistKey.ForMember(member, false); - await file.WriteLineAsync($"* [`{memberKey.Path}`]({mdPath})"); + await file.WriteLineAsync($"* [`{member.Signature}`]({mdPath})"); } + await file.WriteLineAsync(); - await WriteTypeFileAsync(typeGroup, Path.Combine(directory.FullName, mdPath), documentation); + //await WriteTypeFileAsync(typeGroup, Path.Combine(directory.FullName, mdPath), documentation); } } @@ -126,41 +136,40 @@ public async Task SaveAsync(string path) async Task WriteTypeFileAsync(IGrouping typeGroup, string fileName, XDocument documentation) { - using (var file = File.CreateText(fileName)) - { - var typeKey = WhitelistKey.ForType(typeGroup.Key); - await file.WriteLineAsync($"#{typeKey.Path}"); - await file.WriteLineAsync(); - foreach (var member in typeGroup.OrderBy(m => m.Name)) - { - var fullMemberKey = WhitelistKey.ForMember(member); - var xmlKey = fullMemberKey.ToXmlDoc(); - var memberKey = WhitelistKey.ForMember(member, false); - var doc = documentation?.XPathSelectElement($"/doc/members/member[@name='{xmlKey}']"); - string summary; - if (doc != null) - summary = doc.Element("summary")?.Value ?? ""; - else - summary = ""; - await file.WriteLineAsync($"* `{memberKey.Path}`"); - await file.WriteLineAsync($" " + Trim(summary)); - await file.WriteLineAsync(); - } - } + //using (var file = File.CreateText(fileName)) + //{ + // var typeKey = WhitelistKey.ForType(typeGroup.Key); + // await file.WriteLineAsync($"#{typeKey.Path}"); + // await file.WriteLineAsync(); + // foreach (var member in typeGroup.OrderBy(m => m.Name)) + // { + // var fullMemberKey = WhitelistKey.ForMember(member); + // var xmlKey = fullMemberKey.ToXmlDoc(); + // var memberKey = WhitelistKey.ForMember(member, false); + // var doc = documentation?.XPathSelectElement($"/doc/members/member[@name='{xmlKey}']"); + // string summary; + // if (doc != null) + // summary = doc.Element("summary")?.Value ?? ""; + // else + // summary = ""; + // await file.WriteLineAsync($"* `{memberKey.Path}`"); + // await file.WriteLineAsync($" " + Trim(summary)); + // await file.WriteLineAsync(); + // } + //} } - string Trim(string summary) => Regex.Replace(summary.Trim(), @"\s{2,}", " "); - - readonly HashSet _invalidCharacters = new HashSet(Path.GetInvalidFileNameChars()); + string Trim(string summary) + { + return Regex.Replace(summary.Trim(), @"\s{2,}", " "); + } string ToMdFileName(string path) { var builder = new StringBuilder(path); for (var i = 0; i < builder.Length; i++) - { if (_invalidCharacters.Contains(builder[i])) builder[i] = '_'; - } builder.Append(".md"); return builder.ToString(); diff --git a/Source/DocGen/Whitelist.cs b/Source/DocGen/Whitelist.cs index 44c2b52..7928d2e 100644 --- a/Source/DocGen/Whitelist.cs +++ b/Source/DocGen/Whitelist.cs @@ -42,7 +42,7 @@ public bool IsWhitelisted(AssemblyName assemblyName) public bool IsWhitelisted(Type type) { - var typeKey = WhitelistKey.ForType(type); + var typeKey = ApiEntry.Create(type, null); if (typeKey == null) return false; return _entries.Any(key => key.IsMatchFor(typeKey)); @@ -52,7 +52,7 @@ public bool IsWhitelisted(MemberInfo memberInfo) { if (!IsWhitelisted(memberInfo.DeclaringType.Assembly)) return false; - var typeKey = WhitelistKey.ForMember(memberInfo); + var typeKey = ApiEntry.Create(memberInfo, null); return _entries.Any(key => key.IsMatchFor(typeKey)); } } diff --git a/Source/DocGen/WhitelistKey.cs b/Source/DocGen/WhitelistKey.cs index 87b5e08..ce3e47f 100644 --- a/Source/DocGen/WhitelistKey.cs +++ b/Source/DocGen/WhitelistKey.cs @@ -1,6 +1,4 @@ using System; -using System.Linq; -using System.Reflection; using System.Text.RegularExpressions; namespace DocGen @@ -20,135 +18,15 @@ public static bool TryParse(string text, out WhitelistKey entry) var path = text.Substring(0, assemblyNameIndex).Trim(); var regexPattern = "\\A" + Regex.Escape(path.Replace('+', '.')).Replace("\\*", ".*") + "\\z"; var regex = new Regex(regexPattern, RegexOptions.Singleline | RegexOptions.CultureInvariant | RegexOptions.IgnoreCase); - entry = new WhitelistKey(assemblyName, path, regex, null); + entry = new WhitelistKey(assemblyName, path, regex); return true; } - public static WhitelistKey ForType(Type type, bool includeNamespace = true) - { - if (!type.IsPublic && !type.IsNestedPublic && !type.IsNestedFamily && !type.IsNestedFamANDAssem && !type.IsNestedFamORAssem) - return null; - //if (type.IsGenericType) - // type = type.GetGenericTypeDefinition(); - if (type.IsGenericTypeDefinition || type.IsGenericType) - return ForGenericType(type, includeNamespace); - var assemblyName = type.Assembly.GetName().Name; - var path = includeNamespace? type.FullName : type.Name; - return new WhitelistKey(assemblyName, path, null, "T"); - } - - static WhitelistKey ForGenericType(Type type, bool includeNamespace = true) - { - var assemblyName = type.Assembly.GetName().Name; - var path = type.IsGenericType? (includeNamespace? type.GetGenericTypeDefinition().FullName : type.GetGenericTypeDefinition().Name) : (includeNamespace ? type.FullName : type.Name); - var separatorIndex = path.IndexOf('`'); - if (separatorIndex >= 0) - path = path.Substring(0, separatorIndex); - var genericArguments = type.GetGenericArguments(); - path += "<" + string.Join(", ", genericArguments.Select(arg => arg.IsGenericParameter? arg.Name : arg.FullName)) + ">"; - return new WhitelistKey(assemblyName, path, null, "T"); - } - - public static WhitelistKey ForMember(MemberInfo memberInfo, bool includeTypeName = true) - { - switch (memberInfo) - { - case ConstructorInfo constructorInfo: - return ForConstructor(constructorInfo, includeTypeName); - case EventInfo eventInfo: - return ForEvent(eventInfo, includeTypeName); - case FieldInfo fieldInfo: - return ForField(fieldInfo, includeTypeName); - case PropertyInfo propertyInfo: - return ForProperty(propertyInfo, includeTypeName); - case MethodInfo methodInfo: - return ForMethod(methodInfo, includeTypeName); - default: - return null; - } - } - - static WhitelistKey ForConstructor(ConstructorInfo constructorInfo, bool includeTypeName) - { - if (constructorInfo.IsSpecialName || !constructorInfo.IsPublic && !constructorInfo.IsFamily && !constructorInfo.IsFamilyAndAssembly && !constructorInfo.IsFamilyOrAssembly) - return null; - var basis = ForType(constructorInfo.DeclaringType); - var path = includeTypeName? basis.Path + "." + constructorInfo.Name : constructorInfo.Name; - var parameters = constructorInfo.GetParameters(); - path += "(" + string.Join(", ", parameters.Select(ParameterStr)) + ")"; - return new WhitelistKey(basis.AssemblyName, path, null, "C"); - } - - static WhitelistKey ForEvent(EventInfo eventInfo, bool includeTypeName) - { - if (eventInfo.IsSpecialName || !(eventInfo.AddMethod?.IsPublic ?? false) && !(eventInfo.AddMethod?.IsFamily ?? false) && !(eventInfo.AddMethod?.IsFamilyAndAssembly ?? false) && !(eventInfo.AddMethod?.IsFamilyOrAssembly ?? false) - && !(eventInfo.RemoveMethod?.IsPublic ?? false) && !(eventInfo.RemoveMethod?.IsFamily ?? false) && !(eventInfo.RemoveMethod?.IsFamilyAndAssembly ?? false) && !(eventInfo.RemoveMethod?.IsFamilyOrAssembly ?? false)) - return null; - var basis = ForType(eventInfo.DeclaringType); - return new WhitelistKey(basis.AssemblyName, includeTypeName? basis.Path + "." + eventInfo.Name: eventInfo.Name, null, "E"); - } - - static WhitelistKey ForField(FieldInfo fieldInfo, bool includeTypeName) - { - if (fieldInfo.IsSpecialName || !fieldInfo.IsPublic && !fieldInfo.IsFamily && !fieldInfo.IsFamilyAndAssembly && !fieldInfo.IsFamilyOrAssembly) - return null; - var basis = ForType(fieldInfo.DeclaringType); - return new WhitelistKey(basis.AssemblyName, includeTypeName? basis.Path + "." + fieldInfo.Name: fieldInfo.Name, null, "F"); - } - - static WhitelistKey ForProperty(PropertyInfo propertyInfo, bool includeTypeName) - { - if (propertyInfo.IsSpecialName || !(propertyInfo.GetMethod?.IsPublic ?? false) && !(propertyInfo.GetMethod?.IsFamily ?? false) && !(propertyInfo.GetMethod?.IsFamilyAndAssembly ?? false) && !(propertyInfo.GetMethod?.IsFamilyOrAssembly ?? false) - && !(propertyInfo.SetMethod?.IsPublic ?? false) && !(propertyInfo.SetMethod?.IsFamily ?? false) && !(propertyInfo.SetMethod?.IsFamilyAndAssembly ?? false) && !(propertyInfo.SetMethod?.IsFamilyOrAssembly ?? false)) - return null; - var basis = ForType(propertyInfo.DeclaringType); - return new WhitelistKey(basis.AssemblyName, includeTypeName? basis.Path + "." + propertyInfo.Name : propertyInfo.Name, null, "P"); - } - - static WhitelistKey ForMethod(MethodInfo methodInfo, bool includeTypeName) - { - if (methodInfo.IsSpecialName || !methodInfo.IsPublic && !methodInfo.IsFamily && !methodInfo.IsFamilyAndAssembly && !methodInfo.IsFamilyOrAssembly) - return null; - - //if (methodInfo.IsGenericMethod) - // methodInfo = methodInfo.GetGenericMethodDefinition(); - if (methodInfo.IsGenericMethodDefinition || methodInfo.IsGenericMethod) - return ForGenericMethod(methodInfo, includeTypeName); - var basis = ForType(methodInfo.DeclaringType); - var path = includeTypeName? basis.Path + "." + methodInfo.Name : methodInfo.Name; - var parameters = methodInfo.GetParameters(); - path += "(" + string.Join(", ", parameters.Select(ParameterStr)) + ")"; - return new WhitelistKey(basis.AssemblyName, path, null, "M"); - } - - static WhitelistKey ForGenericMethod(MethodInfo methodInfo, bool includeTypeName) - { - var basis = ForType(methodInfo.DeclaringType); - var path = includeTypeName? basis.Path + "." + methodInfo.Name : methodInfo.Name; - var separatorIndex = path.IndexOf('`'); - if (separatorIndex >= 0) - path = path.Substring(0, separatorIndex); - var genericArguments = methodInfo.GetGenericArguments(); - path += "<" + string.Join(", ", genericArguments.Select(arg => arg.Name)) + ">"; - var parameters = methodInfo.GetParameters(); - path += "(" + string.Join(", ", parameters.Select(ParameterStr)) + ")"; - return new WhitelistKey(basis.AssemblyName, path, null, "M"); - } - - static string ParameterStr(ParameterInfo parameterInfo) - { - var prefix = parameterInfo.ParameterType.IsByRef ? "ref " : parameterInfo.ParameterType.IsPointer ? "*" : parameterInfo.IsOut ? "out " : ""; - var type = parameterInfo.ParameterType.IsByRef || parameterInfo.ParameterType.IsPointer ? parameterInfo.ParameterType.GetElementType() : parameterInfo.ParameterType; - return prefix + ForType(type).Path; - } - readonly Regex _regex; - readonly string _typeChar; - WhitelistKey(string assemblyName, string path, Regex regex, string typeChar) + WhitelistKey(string assemblyName, string path, Regex regex) { _regex = regex; - _typeChar = typeChar; AssemblyName = assemblyName; Path = path; } @@ -157,13 +35,11 @@ static string ParameterStr(ParameterInfo parameterInfo) public string Path { get; } - public bool IsMatchFor(WhitelistKey typeKey) + public bool IsMatchFor(ApiEntry apiEntry) { - if (typeKey == null) + if (apiEntry == null) return false; - return string.Equals(AssemblyName, typeKey.AssemblyName, StringComparison.OrdinalIgnoreCase) && _regex.IsMatch(typeKey.Path); + return string.Equals(AssemblyName, apiEntry.AssemblyName, StringComparison.OrdinalIgnoreCase) && _regex.IsMatch(apiEntry.WhitelistKey); } - - public string ToXmlDoc() => $"{_typeChar}:{Path.Replace('<', '{').Replace('>', '}')}"; } } \ No newline at end of file diff --git a/Source/MDK/MDKPackage.GeneratedInfo.cs b/Source/MDK/MDKPackage.GeneratedInfo.cs index 5b680b7..e665295 100644 --- a/Source/MDK/MDKPackage.GeneratedInfo.cs +++ b/Source/MDK/MDKPackage.GeneratedInfo.cs @@ -8,7 +8,7 @@ public partial class MDKPackage /// /// The current package version /// - public static readonly Version Version = new Version("1.1.12"); + public static readonly Version Version = new Version("1.1.13"); /// /// The required IDE version @@ -18,7 +18,7 @@ public partial class MDKPackage /// /// Determines whether this version is a prerelease version /// - public const bool IsPrerelease = true; + public const bool IsPrerelease = false; /// /// Gets the help page navigation URL diff --git a/Source/MDK/other.xml b/Source/MDK/other.xml index 2392568..13de23b 100644 --- a/Source/MDK/other.xml +++ b/Source/MDK/other.xml @@ -1,6 +1,6 @@  - True + False https://github.com/malware-dev/MDK-SE/wiki https://github.com/malware-dev/MDK-SE/releases https://github.com/malware-dev/MDK-SE/issues diff --git a/Source/MDK/source.extension.vsixmanifest b/Source/MDK/source.extension.vsixmanifest index 772a7f0..a2ad6e4 100644 --- a/Source/MDK/source.extension.vsixmanifest +++ b/Source/MDK/source.extension.vsixmanifest @@ -1,7 +1,7 @@  - + MDK/SE A toolkit to help with ingame script (programmable block) development for Keen Software House's space sandbox Space Engineers. diff --git a/Source/MDKServices/ProjectScriptInfo.GeneratedInfo.cs b/Source/MDKServices/ProjectScriptInfo.GeneratedInfo.cs index 929e7ad..3583120 100644 --- a/Source/MDKServices/ProjectScriptInfo.GeneratedInfo.cs +++ b/Source/MDKServices/ProjectScriptInfo.GeneratedInfo.cs @@ -7,6 +7,6 @@ partial class ProjectScriptInfo /// /// The current package version this utility assembly targets /// - public static readonly Version TargetPackageVersion = new Version("1.1.12"); + public static readonly Version TargetPackageVersion = new Version("1.1.13"); } }