diff --git a/DeprecatedRules/AvoidUninitializedVariable.cs b/DeprecatedRules/AvoidUninitializedVariable.cs
deleted file mode 100644
index accbbcc3d..000000000
--- a/DeprecatedRules/AvoidUninitializedVariable.cs
+++ /dev/null
@@ -1,156 +0,0 @@
-//
-// Copyright (c) Microsoft Corporation.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-// THE SOFTWARE.
-//
-
-using System;
-using System.Linq;
-using System.Collections.Generic;
-using System.Management.Automation.Language;
-using Microsoft.Windows.PowerShell.ScriptAnalyzer.Generic;
-using System.ComponentModel.Composition;
-using System.Globalization;
-
-namespace Microsoft.Windows.PowerShell.ScriptAnalyzer.BuiltinRules
-{
- ///
- /// AvoidUnitializedVariable: Check if any uninitialized variable is used.
- ///
- [Export(typeof(IScriptRule))]
- public class AvoidUnitializedVariable : IScriptRule
- {
- ///
- /// AnalyzeScript: Check if any uninitialized variable is used.
- ///
- public IEnumerable AnalyzeScript(Ast ast, string fileName)
- {
- // TODO : We need to find another way for using S.M.A.L.Compiler.GetExpressionValue.
- // Following code are not working for certain scenarios;, like:
- // for ($i=1; $i -le 10; $i++){Write-Host $i}
-
- if (ast == null) throw new ArgumentNullException(Strings.NullAstErrorMessage);
-
- // Finds all VariableExpressionAst
- IEnumerable foundAsts = ast.FindAll(testAst => testAst is VariableExpressionAst, true);
-
- // Iterates all VariableExpressionAst and check the command name.
- foreach (VariableExpressionAst varAst in foundAsts)
- {
- if (Helper.Instance.IsUninitialized(varAst, ast))
- {
- yield return new DiagnosticRecord(string.Format(CultureInfo.CurrentCulture, Strings.AvoidUninitializedVariableError, varAst.VariablePath.UserPath),
- varAst.Extent, GetName(), DiagnosticSeverity.Warning, fileName, varAst.VariablePath.UserPath);
- }
- }
-
- IEnumerable funcAsts = ast.FindAll(item => item is FunctionDefinitionAst, true);
- IEnumerable funcMemberAsts = ast.FindAll(item => item is FunctionMemberAst, true);
-
- foreach (FunctionDefinitionAst funcAst in funcAsts)
- {
- // Finds all VariableExpressionAst.
- IEnumerable varAsts = funcAst.FindAll(testAst => testAst is VariableExpressionAst, true);
-
- HashSet paramVariables = new HashSet();
-
- // don't raise the rules for variables in the param block.
- if (funcAst.Body != null && funcAst.Body.ParamBlock != null && funcAst.Body.ParamBlock.Parameters != null)
- {
- paramVariables.UnionWith(funcAst.Body.ParamBlock.Parameters.Select(paramAst => paramAst.Name.VariablePath.UserPath));
- }
-
- //don't raise the rules for parameters outside the param block
- if(funcAst.Parameters != null)
- {
- paramVariables.UnionWith(funcAst.Parameters.Select(paramAst => paramAst.Name.VariablePath.UserPath));
- }
-
- // Iterates all VariableExpressionAst and check the command name.
- foreach (VariableExpressionAst varAst in varAsts)
- {
- if (Helper.Instance.IsUninitialized(varAst, funcAst) && !paramVariables.Contains(varAst.VariablePath.UserPath))
- {
- yield return new DiagnosticRecord(string.Format(CultureInfo.CurrentCulture, Strings.AvoidUninitializedVariableError, varAst.VariablePath.UserPath),
- varAst.Extent, GetName(), DiagnosticSeverity.Warning, fileName, varAst.VariablePath.UserPath);
- }
- }
- }
-
- foreach (FunctionMemberAst funcMemAst in funcMemberAsts)
- {
- // Finds all VariableExpressionAst.
- IEnumerable varAsts = funcMemAst.FindAll(testAst => testAst is VariableExpressionAst, true);
-
- // Iterates all VariableExpressionAst and check the command name.
- foreach (VariableExpressionAst varAst in varAsts)
- {
- if (Helper.Instance.IsUninitialized(varAst, funcMemAst))
- {
- yield return new DiagnosticRecord(string.Format(CultureInfo.CurrentCulture, Strings.AvoidUninitializedVariableError, varAst.VariablePath.UserPath),
- varAst.Extent, GetName(), DiagnosticSeverity.Warning, fileName, varAst.VariablePath.UserPath);
- }
- }
-
- }
- }
-
- ///
- /// GetName: Retrieves the name of this rule.
- ///
- /// The name of this rule
- public string GetName()
- {
- return string.Format(CultureInfo.CurrentCulture, Strings.NameSpaceFormat, GetSourceName(), Strings.AvoidUninitializedVariableName);
- }
-
- ///
- /// GetCommonName: Retrieves the common name of this rule.
- ///
- /// The common name of this rule
- public string GetCommonName()
- {
- return string.Format(CultureInfo.CurrentCulture, Strings.AvoidUninitializedVariableCommonName);
- }
-
- ///
- /// GetDescription: Retrieves the description of this rule.
- ///
- /// The description of this rule
- public string GetDescription()
- {
- return string.Format(CultureInfo.CurrentCulture, Strings.AvoidUninitializedVariableDescription);
- }
-
- ///
- /// Method: Retrieves the type of the rule: builtin, managed or module.
- ///
- public SourceType GetSourceType()
- {
- return SourceType.Builtin;
- }
-
- ///
- /// GetSeverity: Retrieves the severity of the rule: error, warning of information.
- ///
- ///
- public RuleSeverity GetSeverity()
- {
- return RuleSeverity.Warning;
- }
-
- ///
- /// Method: Retrieves the module/assembly name the rule is from.
- ///
- public string GetSourceName()
- {
- return string.Format(CultureInfo.CurrentCulture, Strings.SourceName);
- }
- }
-}
diff --git a/DeprecatedRules/AvoidUnloadableModule.cs b/DeprecatedRules/AvoidUnloadableModule.cs
deleted file mode 100644
index 5e21ee989..000000000
--- a/DeprecatedRules/AvoidUnloadableModule.cs
+++ /dev/null
@@ -1,131 +0,0 @@
-//
-// Copyright (c) Microsoft Corporation.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-// THE SOFTWARE.
-//
-
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Text.RegularExpressions;
-using System.Threading.Tasks;
-using System.Management.Automation;
-using System.Management.Automation.Language;
-using Microsoft.Windows.Powershell.ScriptAnalyzer.Generic;
-using System.ComponentModel.Composition;
-using System.Resources;
-using System.Globalization;
-using System.Threading;
-using System.Reflection;
-using System.IO;
-
-namespace Microsoft.Windows.Powershell.ScriptAnalyzer.BuiltinRules
-{
- ///
- /// AvoidUnloadableModule: Run Import-Module on parent folder to check whether the module is loaded.
- ///
- [Export(typeof (IScriptRule))]
- public class AvoidUnloadableModule : IScriptRule
- {
- ///
- /// AnalyzeScript: Run Import-Module on parent folder to check whether the module is loaded. From the IScriptRule interface.
- ///
- /// The script's ast
- /// The script's file name
- /// A List of diagnostic results of this rule
- public IEnumerable AnalyzeScript(Ast ast, string fileName)
- {
- if (ast == null) throw new ArgumentNullException(Strings.NullAstErrorMessage);
-
- DirectoryInfo moduleFolder = Directory.GetParent(fileName);
-
- if (!String.Equals(moduleFolder.FullName, Path.GetPathRoot(fileName)))
- {
- Regex reg = new Regex(String.Format(CultureInfo.CurrentCulture, "{0}\\.(dll|psm1|psd1|cdxml|xaml)",
- Regex.Escape(Path.Combine(moduleFolder.FullName, moduleFolder.Name))));
- var moduleFiles = moduleFolder.GetFiles().Where(file => reg.Match(file.FullName).Success).ToList();
-
- if (moduleFiles != null && moduleFiles.Count > 0)
- {
- bool moduleValid = true;
- using (var ps = System.Management.Automation.PowerShell.Create(RunspaceMode.CurrentRunspace))
- {
- try
- {
- ps.AddCommand("Import-Module");
- ps.AddParameter("Name", moduleFolder.FullName);
- ps.Invoke();
-
- if (ps != null && ps.HadErrors)
- {
- moduleValid = false;
- }
- }
- catch (Exception)
- {
- //Catch the exception thrown by ps.Invoke();
- moduleValid = false;
- }
-
- if (!moduleValid)
- {
- yield return new DiagnosticRecord(String.Format(CultureInfo.CurrentCulture,
- Strings.AvoidUnloadableModuleError, moduleFolder.Name, Path.GetFileName(fileName)),
- ast.Extent, GetName(), DiagnosticSeverity.Warning, fileName);
- }
- }
- }
- }
- }
-
- ///
- /// GetName: Retrieves the name of this rule.
- ///
- /// The name of this rule
- public string GetName()
- {
- return string.Format(CultureInfo.CurrentCulture, Strings.NameSpaceFormat, GetSourceName(), Strings.AvoidUnloadableModuleName);
- }
-
- ///
- /// GetCommonName: Retrieves the common name of this rule.
- ///
- /// The common name of this rule
- public string GetCommonName()
- {
- return String.Format(CultureInfo.CurrentCulture, Strings.AvoidUnloadableModuleCommonName);
- }
-
- ///
- /// GetDescription: Retrieves the description of this rule.
- ///
- /// The description of this rule
- public string GetDescription()
- {
- return String.Format(CultureInfo.CurrentCulture, Strings.AvoidUnloadableModuleDescription);
- }
-
- ///
- /// Method: Retrieves the type of the rule: builtin, managed or module.
- ///
- public SourceType GetSourceType()
- {
- return SourceType.Builtin;
- }
-
- ///
- /// Method: Retrieves the module/assembly name the rule is from.
- ///
- public string GetSourceName()
- {
- return string.Format(CultureInfo.CurrentCulture, Strings.SourceName);
- }
- }
-}
diff --git a/DeprecatedRules/AvoidUsingFilePaths.cs b/DeprecatedRules/AvoidUsingFilePaths.cs
deleted file mode 100644
index cc9a9b256..000000000
--- a/DeprecatedRules/AvoidUsingFilePaths.cs
+++ /dev/null
@@ -1,127 +0,0 @@
-//
-// Copyright (c) Microsoft Corporation.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-// THE SOFTWARE.
-//
-
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-using System.Management.Automation.Language;
-using Microsoft.Windows.Powershell.ScriptAnalyzer.Generic;
-using System.ComponentModel.Composition;
-using System.Resources;
-using System.Globalization;
-using System.Threading;
-using System.Reflection;
-using System.IO;
-
-namespace Microsoft.Windows.Powershell.ScriptAnalyzer.BuiltinRules
-{
- ///
- /// AvoidUsingFilePaths: Check that rooted file paths are not used.
- /// Examples of rooted file paths are C:\Users or \\windows\powershell
- ///
- [Export(typeof (IScriptRule))]
- public class AvoidUsingFilePaths : IScriptRule
- {
- ///
- /// AnalyzeScript: Analyzes the ast to check that rooted file paths are not used. From the ILintScriptRule interface.
- ///
- /// The script's ast
- /// The script's file name
- /// A List of diagnostic results of this rule
- public IEnumerable AnalyzeScript(Ast ast, string fileName)
- {
- if (ast == null) throw new ArgumentNullException(Strings.NullAstErrorMessage);
-
- IEnumerable expressionAsts = ast.FindAll(testAst => testAst is StringConstantExpressionAst, true);
-
- if (expressionAsts != null)
- {
- foreach (StringConstantExpressionAst expressionAst in expressionAsts)
- {
- bool isPathValid = false;
- bool isRootedPath = false;
- //make sure there is no path
- char[] invalidPathChars = Path.GetInvalidPathChars();
- if (expressionAst.Value.IndexOfAny(invalidPathChars) < 0)
- {
- isPathValid = true;
- }
-
- if (isPathValid)
- {
- if (Path.IsPathRooted(expressionAst.Value))
- {
- isRootedPath = true;
- }
- }
-
- if (!String.IsNullOrWhiteSpace(expressionAst.Value) && isRootedPath)
- {
- //Exclude the case where there are only slashes in the expressions
- char[] varToTrim = { '/', '\\' };
- if (!String.IsNullOrEmpty(expressionAst.Value.Trim(varToTrim)))
- {
- yield return new DiagnosticRecord(String.Format(CultureInfo.CurrentCulture, Strings.AvoidUsingFilePathError,
- expressionAst.Value, Path.GetFileName(fileName)), expressionAst.Extent,
- GetName(), DiagnosticSeverity.Warning, fileName);
- }
- }
- }
- }
- }
-
- ///
- /// GetName: Retrieves the name of this rule.
- ///
- /// The name of this rule
- public string GetName()
- {
- return string.Format(CultureInfo.CurrentCulture, Strings.NameSpaceFormat, GetSourceName(), Strings.AvoidUsingFilePathName);
- }
-
- ///
- /// GetCommonName: Retrieves the common name of this rule.
- ///
- /// The common name of this rule
- public string GetCommonName()
- {
- return String.Format(CultureInfo.CurrentCulture, Strings.AvoidUsingFilePathCommonName);
- }
-
- ///
- /// GetDescription: Retrieves the description of this rule.
- ///
- /// The description of this rule
- public string GetDescription()
- {
- return string.Format(CultureInfo.CurrentCulture, Strings.AvoidUsingFilePathDescription);
- }
-
- ///
- /// Method: Retrieves the type of the rule: builtin, managed or module.
- ///
- public SourceType GetSourceType()
- {
- return SourceType.Builtin;
- }
-
- ///
- /// Method: Retrieves the module/assembly name the rule is from.
- ///
- public string GetSourceName()
- {
- return string.Format(CultureInfo.CurrentCulture, Strings.SourceName);
- }
- }
-}
diff --git a/DeprecatedRules/AvoidUsingInternalURLs.cs b/DeprecatedRules/AvoidUsingInternalURLs.cs
deleted file mode 100644
index 90c880909..000000000
--- a/DeprecatedRules/AvoidUsingInternalURLs.cs
+++ /dev/null
@@ -1,226 +0,0 @@
-//
-// Copyright (c) Microsoft Corporation.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-// THE SOFTWARE.
-//
-
-using System;
-using System.Collections;
-using System.Collections.Generic;
-using System.Linq;
-using System.Linq.Expressions;
-using System.Management.Automation.Language;
-using Microsoft.Windows.PowerShell.ScriptAnalyzer.Generic;
-using System.ComponentModel.Composition;
-using System.Globalization;
-using System.IO;
-
-namespace Microsoft.Windows.PowerShell.ScriptAnalyzer.BuiltinRules
-{
- ///
- /// AvoidUsingInternalURLs: Check if a URL is potentially an internal URL,
- /// eg://msw, //scratch2/scratch
- ///
- [Export(typeof (IScriptRule))]
- public class AvoidUsingInternalURLs : IScriptRule
- {
- ///
- /// AnalyzeScript: Analyzes the ast to check if any internal URL is used.
- ///
- /// The script's ast
- /// The script's file name
- /// A List of diagnostic results of this rule
- public IEnumerable AnalyzeScript(Ast ast, string fileName)
- {
- if (ast == null) throw new ArgumentNullException(Strings.NullAstErrorMessage);
-
- IEnumerable expressionAsts = ast.FindAll(testAst => testAst is StringConstantExpressionAst, true);
-
- if (expressionAsts != null)
- {
- foreach (StringConstantExpressionAst expressionAst in expressionAsts)
- {
-
- Ast parentAst = expressionAst.Parent;
- //Check if -replace is used, if it is string replace, we don't throw warnings.
- Ast grandParentAst = parentAst.Parent;
- if (grandParentAst is BinaryExpressionAst)
- {
- if ((grandParentAst as BinaryExpressionAst).Operator.Equals(TokenKind.Ireplace))
- {
- continue;
- }
- }
-
- //Check if XPath is used. If XPath is used, then we don't throw warnings.
- if (parentAst is InvokeMemberExpressionAst)
- {
- InvokeMemberExpressionAst invocation = parentAst as InvokeMemberExpressionAst;
- if (invocation != null)
- {
- if (String.Equals(invocation.Member.ToString(), "SelectSingleNode",StringComparison.OrdinalIgnoreCase) ||
- String.Equals(invocation.Member.ToString(), "SelectNodes",StringComparison.OrdinalIgnoreCase) ||
- String.Equals(invocation.Member.ToString(), "Select", StringComparison.OrdinalIgnoreCase) ||
- String.Equals(invocation.Member.ToString(), "Evaluate",StringComparison.OrdinalIgnoreCase) ||
- String.Equals(invocation.Member.ToString(), "Matches",StringComparison.OrdinalIgnoreCase) ||
- String.Equals(invocation.Expression.ToString(), "[System.String]",StringComparison.OrdinalIgnoreCase) ||
- String.Equals(invocation.Expression.ToString(), "[String]", StringComparison.OrdinalIgnoreCase))
- {
- continue;
- }
-
- }
- }
-
-
- bool isPathValid = false;
- bool isInternalURL = false;
- //make sure there is no path
- char[] invalidPathChars = Path.GetInvalidPathChars();
- if (expressionAst.Value.IndexOfAny(invalidPathChars) < 0)
- {
- isPathValid = true;
- }
-
- //Check if path is UNC or begins with "http:" or "www"
- if (isPathValid && ((!String.IsNullOrWhiteSpace(expressionAst.Value))) &&
- (Path.IsPathRooted(expressionAst.Value) ||
- expressionAst.Value.StartsWith("http:", StringComparison.CurrentCultureIgnoreCase)) ||
- (expressionAst.Value.StartsWith("www", StringComparison.CurrentCultureIgnoreCase)))
- {
- //Exclude the case where there are only slashes in the expressions
- char[] varToTrim = {'/','\\'};
- string noSlash = expressionAst.Value.Trim(varToTrim);
- if (!String.IsNullOrEmpty(noSlash) && noSlash.Trim().Length > 1)
- {
- //Check if the string contains two back or forward slashes, such as: \\scratch2\scratch or http:\\www.google.com
- bool backSlash = expressionAst.Value.Contains(@"\\");
- bool forwardSlash = expressionAst.Value.Contains(@"//");
- string firstPartURL = "";
- if (backSlash)
- {
- //Get the first part of the URL before the first back slash, eg: \\scratch2\scratch we check only scratch2 as the first part
- string trimmedAddress =
- expressionAst.Value.Substring(expressionAst.Value.IndexOf(@"\\") + 2);
- if (trimmedAddress.Contains(@"\"))
- {
- firstPartURL = trimmedAddress.Substring(0, trimmedAddress.IndexOf(@"\"));
- }
- else
- {
- firstPartURL = trimmedAddress;
- }
- }
- else if (forwardSlash)
- {
- //Get the first part of the URL before the first forward slash
- string trimmedAddress =
- expressionAst.Value.Substring(expressionAst.Value.IndexOf(@"//") + 2);
- if (trimmedAddress.Contains(@"/"))
- {
- firstPartURL = trimmedAddress.Substring(0, trimmedAddress.IndexOf(@"/"));
- }
- else
- {
- firstPartURL = trimmedAddress;
- }
- }
- else
- {
- if (expressionAst.Value.Contains(@"\"))
- {
- firstPartURL = expressionAst.Value.Substring(0, expressionAst.Value.IndexOf(@"\"));
- }
- else if (expressionAst.Value.Contains(@"/"))
- {
- firstPartURL = expressionAst.Value.Substring(0, expressionAst.Value.IndexOf(@"/"));
- }
- else
- {
- firstPartURL = expressionAst.Value;
- }
- }
- if (!firstPartURL.Contains("."))
- {
- isInternalURL = true;
- //Add a check to exclude potential SDDL format. Check if a string have four components separated by ":"
- var count = firstPartURL.Count(x => x == ':');
- if (count == 3 || count == 4 )
- {
- isInternalURL = false;
- }
- }
- }
- if (isInternalURL)
- {
- yield return
- new DiagnosticRecord(
- String.Format(CultureInfo.CurrentCulture, Strings.AvoidUsingInternalURLsError,
- expressionAst.Value), expressionAst.Extent,
- GetName(), DiagnosticSeverity.Information, fileName);
-
- }
- }
- }
- }
- }
-
- ///
- /// GetName: Retrieves the name of this rule.
- ///
- /// The name of this rule
- public string GetName()
- {
- return string.Format(CultureInfo.CurrentCulture, Strings.NameSpaceFormat, GetSourceName(), Strings.AvoidUsingInternalURLsName);
- }
-
- ///
- /// GetCommonName: Retrieves the common name of this rule.
- ///
- /// The common name of this rule
- public string GetCommonName()
- {
- return String.Format(CultureInfo.CurrentCulture, Strings.AvoidUsingInternalURLsCommonName);
- }
-
- ///
- /// GetDescription: Retrieves the description of this rule.
- ///
- /// The description of this rule
- public string GetDescription()
- {
- return string.Format(CultureInfo.CurrentCulture, Strings.AvoidUsingInternalURLsDescription);
- }
-
- ///
- /// Method: Retrieves the type of the rule: builtin, managed or module.
- ///
- public SourceType GetSourceType()
- {
- return SourceType.Builtin;
- }
-
- ///
- /// GetSeverity: Retrieves the severity of the rule: error, warning of information.
- ///
- ///
- public RuleSeverity GetSeverity()
- {
- return RuleSeverity.Information;
- }
-
- ///
- /// Method: Retrieves the module/assembly name the rule is from.
- ///
- public string GetSourceName()
- {
- return string.Format(CultureInfo.CurrentCulture, Strings.SourceName);
- }
- }
-}