<commit_before>﻿using System;
using System.Collections.ObjectModel;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Management.Automation;
using System.Management.Automation.Language;
using Microsoft.Windows.Powershell.ScriptAnalyzer.Generic;
using Microsoft.Windows.Powershell.ScriptAnalyzer;
using System.ComponentModel.Composition;
using System.Resources;
using System.Globalization;
using System.Threading;
using System.Reflection;

namespace Microsoft.Windows.Powershell.ScriptAnalyzer.BuiltinRules
{
    /// <summary>
    /// AvoidUnitializedVariable: Check if any uninitialized variable is used.
    /// </summary>
    [Export(typeof(IScriptRule))]
    public class AvoidUnitializedVariable : IScriptRule
    {
        /// <summary>
        /// AnalyzeScript: Check if any uninitialized variable is used.
        /// </summary>
        public IEnumerable<DiagnosticRecord> 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<Ast> 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);
                }
            }

            IEnumerable<Ast> funcAsts = ast.FindAll(item => item is FunctionDefinitionAst, true);

            foreach (var funcAst in funcAsts)
            {
                // Finds all VariableExpressionAst.
                IEnumerable<Ast> varAsts = funcAst.FindAll(testAst => testAst is VariableExpressionAst, true);

                // Iterates all VariableExpressionAst and check the command name.
                foreach (VariableExpressionAst varAst in varAsts)
                {
                    if (Helper.Instance.IsUninitialized(varAst, funcAst))
                    {
                        yield return new DiagnosticRecord(string.Format(CultureInfo.CurrentCulture, Strings.AvoidUninitializedVariableError, varAst.VariablePath.UserPath),
                            varAst.Extent, GetName(), DiagnosticSeverity.Warning, fileName);
                    }
                }
            }
        }
<commit_msg>Make UninitializedVariable recognize functions in dsc classes<commit_after>﻿using System;
using System.Collections.ObjectModel;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Management.Automation;
using System.Management.Automation.Language;
using Microsoft.Windows.Powershell.ScriptAnalyzer.Generic;
using Microsoft.Windows.Powershell.ScriptAnalyzer;
using System.ComponentModel.Composition;
using System.Resources;
using System.Globalization;
using System.Threading;
using System.Reflection;

namespace Microsoft.Windows.Powershell.ScriptAnalyzer.BuiltinRules
{
    /// <summary>
    /// AvoidUnitializedVariable: Check if any uninitialized variable is used.
    /// </summary>
    [Export(typeof(IScriptRule))]
    public class AvoidUnitializedVariable : IScriptRule
    {
        /// <summary>
        /// AnalyzeScript: Check if any uninitialized variable is used.
        /// </summary>
        public IEnumerable<DiagnosticRecord> 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<Ast> 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);
                }
            }

            IEnumerable<Ast> funcAsts = ast.FindAll(item => item is FunctionDefinitionAst || item is FunctionMemberAst, true);

            foreach (var funcAst in funcAsts)
            {
                // Finds all VariableExpressionAst.
                IEnumerable<Ast> varAsts = funcAst.FindAll(testAst => testAst is VariableExpressionAst, true);

                // Iterates all VariableExpressionAst and check the command name.
                foreach (VariableExpressionAst varAst in varAsts)
                {
                    if (Helper.Instance.IsUninitialized(varAst, funcAst))
                    {
                        yield return new DiagnosticRecord(string.Format(CultureInfo.CurrentCulture, Strings.AvoidUninitializedVariableError, varAst.VariablePath.UserPath),
                            varAst.Extent, GetName(), DiagnosticSeverity.Warning, fileName);
                    }
                }
            }
        }

{'fraction_non_alphanumeric': 0.08354387737914772, 'fraction_numerical': 0.001010611419909045, 'mean_word_length': 2.4264281592613965, 'pattern_counts': {'":': 0, '<': 19, '<?xml version=': 0, '>': 25, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5195294', 'n_tokens_mistral': 1557, 'n_tokens_neox': 1450, 'n_words': 367}