@@ -8,11 +8,16 @@ namespace Microsoft.Windows.PowerShell.ScriptAnalyzer.Generic
8
8
// This is still an experimental class. Use at your own risk!
9
9
public abstract class ConfigurableScriptRule : IScriptRule
10
10
{
11
- // Configurable rules should define a default value
11
+ // Configurable rule properties should define a default value
12
12
// because if reading the configuration fails
13
13
// we use the property's default value
14
- [ ConfigurableRuleProperty ( ) ]
15
- public bool Enable { get ; protected set ; } = false ;
14
+ [ ConfigurableRuleProperty ( defaultValue : false ) ]
15
+ public bool Enable { get ; protected set ; }
16
+
17
+ protected ConfigurableScriptRule ( )
18
+ {
19
+ SetDefaultValues ( ) ;
20
+ }
16
21
17
22
public virtual void ConfigureRule ( IDictionary < string , object > paramValueMap )
18
23
{
@@ -23,29 +28,37 @@ public virtual void ConfigureRule(IDictionary<string, object> paramValueMap)
23
28
24
29
try
25
30
{
26
- var properties = GetConfigurableProperties ( ) ;
27
- foreach ( var property in properties )
31
+ foreach ( var property in GetConfigurableProperties ( ) )
28
32
{
29
33
if ( paramValueMap . ContainsKey ( property . Name ) )
30
34
{
31
- var type = property . PropertyType ;
32
- var obj = paramValueMap [ property . Name ] ;
33
-
34
- // TODO Check if type is convertible
35
- property . SetValue (
36
- this ,
37
- System . Convert . ChangeType ( obj , type ) ) ;
35
+ SetValue ( property , paramValueMap [ property . Name ] ) ;
38
36
}
39
37
}
40
38
}
41
39
catch
42
40
{
43
41
// we do not know how to handle an exception in this case yet!
44
- // but we know that this should not crash the program hence we
45
- // have this empty catch block
42
+ // but we know that this should not crash the program
43
+ // hence we revert the property values to their default
44
+ SetDefaultValues ( ) ;
45
+ }
46
+ }
47
+
48
+ private void SetDefaultValues ( )
49
+ {
50
+ foreach ( var property in GetConfigurableProperties ( ) )
51
+ {
52
+ SetValue ( property , GetDefaultValue ( property ) ) ;
46
53
}
47
54
}
48
55
56
+ private void SetValue ( PropertyInfo property , object value )
57
+ {
58
+ // TODO Check if type is convertible
59
+ property . SetValue ( this , Convert . ChangeType ( value , property . PropertyType ) ) ;
60
+ }
61
+
49
62
private IEnumerable < PropertyInfo > GetConfigurableProperties ( )
50
63
{
51
64
foreach ( var property in this . GetType ( ) . GetProperties ( ) )
@@ -57,6 +70,19 @@ private IEnumerable<PropertyInfo> GetConfigurableProperties()
57
70
}
58
71
}
59
72
73
+ private Object GetDefaultValue ( PropertyInfo property )
74
+ {
75
+ var attr = property . GetCustomAttribute ( typeof ( ConfigurableRulePropertyAttribute ) ) ;
76
+ if ( attr == null )
77
+ {
78
+ throw new ArgumentException (
79
+ String . Format ( Strings . ConfigurableScriptRulePropertyHasNotAttribute , property . Name ) ,
80
+ nameof ( property ) ) ;
81
+ }
82
+
83
+ return ( ( ConfigurableRulePropertyAttribute ) attr ) . DefaultValue ;
84
+ }
85
+
60
86
public abstract IEnumerable < DiagnosticRecord > AnalyzeScript ( Ast ast , string fileName ) ;
61
87
public abstract string GetCommonName ( ) ;
62
88
public abstract string GetDescription ( ) ;
@@ -69,6 +95,16 @@ private IEnumerable<PropertyInfo> GetConfigurableProperties()
69
95
[ AttributeUsage ( AttributeTargets . Property , AllowMultiple = false ) ]
70
96
public class ConfigurableRulePropertyAttribute : Attribute
71
97
{
98
+ public object DefaultValue { get ; private set ; }
72
99
100
+ public ConfigurableRulePropertyAttribute ( object defaultValue )
101
+ {
102
+ if ( defaultValue == null )
103
+ {
104
+ throw new ArgumentNullException ( nameof ( defaultValue ) , Strings . ConfigurableScriptRuleNRE ) ;
105
+ }
106
+
107
+ DefaultValue = defaultValue ;
108
+ }
73
109
}
74
110
}
0 commit comments