Skip to content

Commit

Permalink
Abstract and move filter functionality to Microsoft.DocAsCode.Metadat…
Browse files Browse the repository at this point in the history
…a.ManagedReference.Common (#2468)

* Move Filters from Microsoft.DocAsCode.Metadata.ManagedReference.Roslyn to Microsoft.DocAsCode.Metadata.ManagedReference.Common.

- Does not build yet due to necessary changes that will be provided
  in following commit.

* Abstract filter functions.

- Introduce AttributeFilterData and SymbolFilterData that store information about a symbol necessary for filtering.
- Make fiter rules work with these two classes.
- Move Roslyn-specific code to RoslynFilterData.
- Move filter config file loading code into ConfigFilterRule.

* Remove extra space between method name and bracket.
  • Loading branch information
surban authored and superyyrrzz committed Mar 5, 2018
1 parent 9484594 commit b847c75
Show file tree
Hide file tree
Showing 17 changed files with 278 additions and 207 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
// Copyright (c) Microsoft. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.

namespace Microsoft.DocAsCode.Metadata.ManagedReference
{
using System.Collections.Generic;

public class AttributeFilterData
{
public string Id { get; set; }

public IEnumerable<string> ConstructorArguments { get; set; }

public IDictionary<string, string> ConstructorNamedArguments { get; set; }
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
// Copyright (c) Microsoft. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.

namespace Microsoft.DocAsCode.Metadata.ManagedReference
{
using System;
using System.Collections.Generic;
using System.Linq;

using YamlDotNet.Serialization;

[Serializable]
public class AttributeFilterInfo
{
[YamlMember(Alias = "uid")]
public string Uid { get; set; }

[YamlMember(Alias = "ctorArguments")]
public List<string> ConstructorArguments { get; set; } = new List<string>();

[YamlMember(Alias = "ctorNamedArguments")]
public Dictionary<string, string> ConstructorNamedArguments { get; set; } = new Dictionary<string, string>();

public bool ContainedIn(SymbolFilterData symbol)
{
bool result = false;
var attributes = symbol.Attributes;
foreach (var attribute in attributes)
{
if (Uid != attribute.Id)
{
continue;
}

// arguments need to be a total match of the config
if (!ConstructorArguments.SequenceEqual(attribute.ConstructorArguments))
{
continue;
}

// namedarguments need to be a superset of the config
if (!ConstructorNamedArguments.Except(attribute.ConstructorNamedArguments).Any())
{
result = true;
break;
}
}

return result;
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
// Copyright (c) Microsoft. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.

namespace Microsoft.DocAsCode.Metadata.ManagedReference
{
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;

using YamlDotNet.Serialization;

using Microsoft.DocAsCode.Common;

[Serializable]
public class ConfigFilterRule
{
[YamlMember(Alias = "apiRules")]
public List<ConfigFilterRuleItemUnion> ApiRules { get; set; } = new List<ConfigFilterRuleItemUnion>();

[YamlMember(Alias = "attributeRules")]
public List<ConfigFilterRuleItemUnion> AttributeRules { get; set; } = new List<ConfigFilterRuleItemUnion>();

public bool CanVisitApi(SymbolFilterData symbol)
{
return this.CanVisitCore(this.ApiRules, symbol);
}

public bool CanVisitAttribute(SymbolFilterData symbol)
{
return this.CanVisitCore(this.AttributeRules, symbol);
}

private bool CanVisitCore(IEnumerable<ConfigFilterRuleItemUnion> ruleItems, SymbolFilterData symbol)
{
foreach (var ruleUnion in ruleItems)
{
ConfigFilterRuleItem rule = ruleUnion.Rule;
if (rule != null && rule.IsMatch(symbol))
{
return rule.CanVisit;
}
}
return true;
}

public static ConfigFilterRule Load(string configFile)
{
if (string.IsNullOrEmpty(configFile))
{
return new ConfigFilterRule();
}
if (!File.Exists(configFile)) throw new FileNotFoundException($"Filter Config file {configFile} does not exist!");

ConfigFilterRule rule = null;
try
{
rule = YamlUtility.Deserialize<ConfigFilterRule>(configFile);
}
catch (Exception e)
{
throw new InvalidDataException($"Error parsing filter config file {configFile}: {e.Message}");
}

if (rule == null)
{
throw new InvalidDataException($"Unable to deserialize filter config {configFile}.");
}
return rule;
}

public static ConfigFilterRule LoadWithDefaults(string filterConfigFile)
{
ConfigFilterRule defaultRule, userRule;

var assembly = Assembly.GetExecutingAssembly();
var defaultConfigPath = $"{assembly.GetName().Name}.Filters.defaultfilterconfig.yml";
using (var stream = assembly.GetManifestResourceStream(defaultConfigPath))
using (var reader = new StreamReader(stream))
{
defaultRule = YamlUtility.Deserialize<ConfigFilterRule>(reader);
}

if (string.IsNullOrEmpty(filterConfigFile))
{
return defaultRule;
}
else
{
userRule = Load(filterConfigFile);
return Merge(defaultRule, userRule);
}
}

private static ConfigFilterRule Merge(ConfigFilterRule defaultRule, ConfigFilterRule userRule)
{
return new ConfigFilterRule
{
// user rule always overwrite default rule
ApiRules = userRule.ApiRules.Concat(defaultRule.ApiRules).ToList(),
AttributeRules = userRule.AttributeRules.Concat(defaultRule.AttributeRules).ToList(),
};
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ namespace Microsoft.DocAsCode.Metadata.ManagedReference
using System;
using System.Text.RegularExpressions;

using Microsoft.CodeAnalysis;
using YamlDotNet.Serialization;

public abstract class ConfigFilterRuleItem
Expand Down Expand Up @@ -35,13 +34,13 @@ public string UidRegex
[YamlIgnore]
public abstract bool CanVisit { get; }

public bool IsMatch(ISymbol symbol)
public bool IsMatch(SymbolFilterData symbol)
{
if (symbol == null)
{
throw new ArgumentNullException("symbol");
}
var id = VisitorHelper.GetId(symbol);
var id = symbol.Id;

return (_uidRegex == null || (id != null && _uidRegex.IsMatch(id))) &&
(Kind == null || Kind.Value.Contains(symbol)) &&
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ namespace Microsoft.DocAsCode.Metadata.ManagedReference
using System;
using System.IO;

using Microsoft.DocAsCode.DataContracts.Common;
using YamlDotNet.Serialization;

[Serializable]
Expand Down Expand Up @@ -49,7 +48,7 @@ public ConfigFilterRuleExcludeItem Exclude
}
}

internal ConfigFilterRuleItem Rule
public ConfigFilterRuleItem Rule
{
get
{
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
// Copyright (c) Microsoft. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.

namespace Microsoft.DocAsCode.Metadata.ManagedReference
{
public enum ExtendedSymbolKind
{
Assembly = 0x100,
Namespace = 0x110,
Type = 0x120,
Class,
Struct,
Enum,
Interface,
Delegate,
Member = 0x200,
Event,
Field,
Method,
Property,
}

public static class ExtendedSymbolKindHelper
{
public static bool Contains(this ExtendedSymbolKind kind, SymbolFilterData symbol)
{
ExtendedSymbolKind? k = symbol.Kind;

if (k == null)
{
return false;
}
return (kind & k.Value) == kind;
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
// Copyright (c) Microsoft. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.

namespace Microsoft.DocAsCode.Metadata.ManagedReference
{
using System.Collections.Generic;

public class SymbolFilterData
{
public string Id { get; set; }

public ExtendedSymbolKind? Kind { get; set; }

public IEnumerable<AttributeFilterData> Attributes { get; set; }
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

<ItemGroup>
<EmbeddedResource Include="Transform\**" Exclude="bin\**;obj\**;**\*.xproj;packages\**;@(EmbeddedResource)" />
<EmbeddedResource Include="Filters\defaultfilterconfig.yml" Exclude="bin\**;obj\**;**\*.xproj;packages\**;@(EmbeddedResource)" />
</ItemGroup>

<ItemGroup>
Expand Down

This file was deleted.

This file was deleted.

Loading

0 comments on commit b847c75

Please sign in to comment.