/// <summary>
        /// Gets the correction extent
        /// </summary>
        /// <param name="ast"></param>
        /// <returns>A List of CorrectionExtent</returns>
        private List <CorrectionExtent> GetCorrectionExtent(HashtableAst ast)
        {
            int startLineNumber;
            int startColumnNumber;

            // for empty hashtable insert after after "@{"
            if (ast.KeyValuePairs.Count == 0)
            {
                // check if ast starts with "@{"
                if (ast.Extent.Text.IndexOf("@{") != 0)
                {
                    return(null);
                }
                startLineNumber   = ast.Extent.StartLineNumber;
                startColumnNumber = ast.Extent.StartColumnNumber + 2; // 2 for "@{",
            }
            else // for non-empty hashtable insert after the last element
            {
                int maxLine = 0;
                int lastCol = 0;
                foreach (var keyVal in ast.KeyValuePairs)
                {
                    if (keyVal.Item2.Extent.EndLineNumber > maxLine)
                    {
                        maxLine = keyVal.Item2.Extent.EndLineNumber;
                        lastCol = keyVal.Item2.Extent.EndColumnNumber;
                    }
                }
                startLineNumber   = maxLine;
                startColumnNumber = lastCol;
            }

            var    correctionExtents = new List <CorrectionExtent>();
            string fieldName         = "ModuleVersion";
            string fieldValue        = "1.0.0.0";
            string description       = string.Format(
                CultureInfo.CurrentCulture,
                Strings.MissingModuleManifestFieldCorrectionDescription,
                fieldName,
                fieldValue);
            var correctionTextTemplate = @"
# Version number of this module.
{0} = '{1}'
";
            var correctionText         = string.Format(
                correctionTextTemplate,
                fieldName,
                fieldValue);
            var correctionExtent = new CorrectionExtent(
                startLineNumber,
                startLineNumber,
                startColumnNumber,
                startColumnNumber,
                correctionText,
                ast.Extent.File,
                description);

            correctionExtents.Add(correctionExtent);
            return(correctionExtents);
        }
Example #2
0
        private IEnumerable <CorrectionExtent> GetCorrectionExtent(BinaryExpressionAst binaryExpressionAst)
        {
            var correction = new CorrectionExtent(
                binaryExpressionAst.Extent.StartLineNumber,
                binaryExpressionAst.Extent.EndLineNumber,
                binaryExpressionAst.Extent.StartColumnNumber,
                binaryExpressionAst.Extent.EndColumnNumber,
                $"{binaryExpressionAst.Right.Extent.Text} {binaryExpressionAst.ErrorPosition.Text} {binaryExpressionAst.Left.Extent.Text}",
                binaryExpressionAst.Extent.File,
                Strings.PossibleIncorrectComparisonWithNullSuggesteCorrectionDescription
                );

            yield return(correction);
        }
        private CorrectionExtent Normalize(
            Position refPosition,
            CorrectionExtent correctionExtent)
        {
            var shiftedRange = Range.Normalize(refPosition, (Range)correctionExtent);

            return(new CorrectionExtent(
                       shiftedRange.Start.Line,
                       shiftedRange.End.Line,
                       shiftedRange.Start.Column,
                       shiftedRange.End.Column,
                       correctionExtent.Text,
                       correctionExtent.File,
                       correctionExtent.Description));
        }
        private IEnumerable <CorrectionExtent> GetCorrectionExtent(CommandAst commandAst, string correctlyCaseName)
        {
            var description = string.Format(
                CultureInfo.CurrentCulture,
                Strings.UseCorrectCasingDescription,
                correctlyCaseName,
                correctlyCaseName);
            var cmdExtent  = GetCommandExtent(commandAst);
            var correction = new CorrectionExtent(
                cmdExtent.StartLineNumber,
                cmdExtent.EndLineNumber,
                cmdExtent.StartColumnNumber,
                cmdExtent.EndColumnNumber,
                correctlyCaseName,
                commandAst.Extent.File,
                description);

            yield return(correction);
        }
Example #5
0
        private IEnumerable <DiagnosticRecord> FindParameterViolations(Ast ast)
        {
            IEnumerable <Ast> commandAsts = ast.FindAll(
                testAst => testAst is CommandAst, true);

            foreach (CommandAst commandAst in commandAsts)
            {
                List <Ast> commandParameterAstElements = commandAst.FindAll(
                    testAst => testAst.Parent == commandAst, searchNestedScriptBlocks: false).ToList();
                for (int i = 0; i < commandParameterAstElements.Count - 1; i++)
                {
                    IScriptExtent leftExtent  = commandParameterAstElements[i].Extent;
                    IScriptExtent rightExtent = commandParameterAstElements[i + 1].Extent;
                    if (leftExtent.EndLineNumber != rightExtent.StartLineNumber)
                    {
                        continue;
                    }

                    var expectedStartColumnNumberOfRightExtent = leftExtent.EndColumnNumber + 1;
                    if (rightExtent.StartColumnNumber > expectedStartColumnNumberOfRightExtent)
                    {
                        int numberOfRedundantWhiteSpaces = rightExtent.StartColumnNumber - expectedStartColumnNumberOfRightExtent;
                        var correction = new CorrectionExtent(
                            startLineNumber: leftExtent.StartLineNumber,
                            endLineNumber: leftExtent.EndLineNumber,
                            startColumnNumber: leftExtent.EndColumnNumber + 1,
                            endColumnNumber: leftExtent.EndColumnNumber + 1 + numberOfRedundantWhiteSpaces,
                            text: string.Empty,
                            file: leftExtent.File);

                        yield return(new DiagnosticRecord(
                                         GetError(ErrorKind.BetweenParameter),
                                         leftExtent,
                                         GetName(),
                                         GetDiagnosticSeverity(),
                                         leftExtent.File,
                                         suggestedCorrections: new CorrectionExtent[] { correction }));
                    }
                }
            }
        }
        private IEnumerable <CorrectionExtent> GetCorrectionExtent(CommandParameterAst commandParameterAst, string correctlyCaseName)
        {
            var description = string.Format(
                CultureInfo.CurrentCulture,
                Strings.UseCorrectCasingDescription,
                correctlyCaseName,
                correctlyCaseName);
            var cmdExtent  = commandParameterAst.Extent;
            var correction = new CorrectionExtent(
                cmdExtent.StartLineNumber,
                cmdExtent.EndLineNumber,
                // +1 because of the dash before the parameter name
                cmdExtent.StartColumnNumber + 1,
                // do not use EndColumnNumber property as it would not cover the case where the colon syntax: -ParameterName:$ParameterValue
                cmdExtent.StartColumnNumber + 1 + commandParameterAst.ParameterName.Length,
                correctlyCaseName,
                commandParameterAst.Extent.File,
                description);

            yield return(correction);
        }
Example #7
0
            public override AstVisitAction VisitTernaryExpression(TernaryExpressionAst ternaryExpressionAst)
            {
                if (!TargetsNonPS7())
                {
                    return(AstVisitAction.Continue);
                }

                var correction = new CorrectionExtent(
                    ternaryExpressionAst.Extent,
                    $"if ({ternaryExpressionAst.Condition.Extent.Text}) {{ {ternaryExpressionAst.IfTrue.Extent.Text} }} else {{ {ternaryExpressionAst.IfFalse.Extent.Text} }}",
                    _analyzedFilePath);

                AddDiagnostic(
                    ternaryExpressionAst,
                    "ternary expression",
                    "<test> ? <exp1> : <exp2>",
                    "3,4,5,6",
                    correction);

                return(AstVisitAction.Continue);
            }
Example #8
0
            private void AddDiagnostic(
                Ast offendingAst,
                string syntaxName,
                string syntaxExample,
                string unsupportedVersions,
                CorrectionExtent correction = null)
            {
                string message = string.Format(
                    CultureInfo.CurrentCulture,
                    Strings.UseCompatibleSyntaxError,
                    syntaxName,
                    syntaxExample,
                    unsupportedVersions);

                if (correction == null)
                {
                    _diagnosticAccumulator.Add(
                        new DiagnosticRecord(
                            message,
                            offendingAst.Extent,
                            _rule.GetName(),
                            _rule.Severity,
                            _analyzedFilePath));

                    return;
                }

                _diagnosticAccumulator.Add(
                    new DiagnosticRecord(
                        message,
                        offendingAst.Extent,
                        _rule.GetName(),
                        _rule.Severity,
                        _analyzedFilePath,
                        ruleId: null,
                        new[] { correction }));
            }
            public override AstVisitAction VisitInvokeMemberExpression(InvokeMemberExpressionAst methodCallAst)
            {
                // Look for [typename]::new(...) and [typename]::$dynamicMethodName syntax

                if (!_targetVersions.Contains(s_v3) && !_targetVersions.Contains(s_v4))
                {
                    return(AstVisitAction.Continue);
                }

                if (_targetVersions.Contains(s_v3) && methodCallAst.Member is VariableExpressionAst)
                {
                    string message = string.Format(
                        CultureInfo.CurrentCulture,
                        Strings.UseCompatibleSyntaxError,
                        "dynamic method invocation",
                        methodCallAst.Extent.Text,
                        "3");

                    _diagnosticAccumulator.Add(new DiagnosticRecord(
                                                   message,
                                                   methodCallAst.Extent,
                                                   _rule.GetName(),
                                                   _rule.Severity,
                                                   _analyzedFilePath
                                                   ));
                }

                if (!(methodCallAst.Expression is TypeExpressionAst typeExpressionAst))
                {
                    return(AstVisitAction.Continue);
                }

                if (!(methodCallAst.Member is StringConstantExpressionAst stringConstantAst))
                {
                    return(AstVisitAction.Continue);
                }

                if (stringConstantAst.Value.Equals("new", StringComparison.OrdinalIgnoreCase))
                {
                    string typeName = typeExpressionAst.TypeName.FullName;

                    CorrectionExtent suggestedCorrection = CreateNewObjectCorrection(
                        _analyzedFilePath,
                        methodCallAst.Extent,
                        typeName,
                        methodCallAst.Arguments);

                    string message = string.Format(
                        CultureInfo.CurrentCulture,
                        Strings.UseCompatibleSyntaxError,
                        "constructor",
                        methodCallAst.Extent.Text,
                        "3,4");

                    _diagnosticAccumulator.Add(new DiagnosticRecord(
                                                   message,
                                                   methodCallAst.Extent,
                                                   _rule.GetName(),
                                                   _rule.Severity,
                                                   _analyzedFilePath,
                                                   ruleId: null,
                                                   suggestedCorrections: new [] { suggestedCorrection }
                                                   ));

                    return(AstVisitAction.Continue);
                }

                return(AstVisitAction.Continue);
            }
        /// <summary>
        /// Gets the correction extent
        /// </summary>
        /// <param name="ast"></param>
        /// <returns>A List of CorrectionExtent</returns>
        private List<CorrectionExtent> GetCorrectionExtent(HashtableAst ast)
        {
            int startLineNumber;
            int startColumnNumber;

            // for empty hashtable insert after after "@{"
            if (ast.KeyValuePairs.Count == 0)
            {
                // check if ast starts with "@{"
                if (ast.Extent.Text.IndexOf("@{") != 0)
                {
                    return null;
                }
                startLineNumber = ast.Extent.StartLineNumber;
                startColumnNumber = ast.Extent.StartColumnNumber + 2; // 2 for "@{",
            }
            else // for non-empty hashtable insert after the last element
            {
                int maxLine = 0;
                int lastCol = 0;
                foreach (var keyVal in ast.KeyValuePairs)
                {
                    if (keyVal.Item2.Extent.EndLineNumber > maxLine)
                    {
                        maxLine = keyVal.Item2.Extent.EndLineNumber;
                        lastCol = keyVal.Item2.Extent.EndColumnNumber;
                    }
                }
                startLineNumber = maxLine;
                startColumnNumber = lastCol;
            }

            var correctionExtents = new List<CorrectionExtent>();
            string fieldName = "ModuleVersion";
            string fieldValue = "1.0.0.0";
            string description = string.Format(
                CultureInfo.CurrentCulture,
                Strings.MissingModuleManifestFieldCorrectionDescription,
                fieldName,
                fieldValue);
            var correctionTextTemplate = @"
            # Version number of this module.
            {0} = '{1}'
            ";
            var correctionText = string.Format(
                correctionTextTemplate,
                fieldName,
                fieldValue);
            var correctionExtent = new CorrectionExtent(
                startLineNumber,
                startLineNumber,
                startColumnNumber,
                startColumnNumber,
                correctionText,
                ast.Extent.File,
                description);
            correctionExtents.Add(correctionExtent);
            return correctionExtents;
        }
Example #11
0
            public override AstVisitAction VisitInvokeMemberExpression(InvokeMemberExpressionAst methodCallAst)
            {
                // Look for [typename]::new(...) and [typename]::$dynamicMethodName syntax

#if PSV7
                if (!TargetsNonPS7())
                {
                    return(AstVisitAction.Continue);
                }

                if (methodCallAst.NullConditional)
                {
                    AddDiagnostic(
                        methodCallAst,
                        "null-conditional method invocation",
                        "${x}?.Method()",
                        "3,4,5,6");
                }
#endif

                if (!_targetVersions.Contains(s_v3) && !_targetVersions.Contains(s_v4))
                {
                    return(AstVisitAction.Continue);
                }

                if (_targetVersions.Contains(s_v3) && methodCallAst.Member is VariableExpressionAst)
                {
                    AddDiagnostic(
                        methodCallAst,
                        "dynamic method invocation",
                        "$x.$method()",
                        "3");
                }

                if (!(methodCallAst.Expression is TypeExpressionAst typeExpressionAst))
                {
                    return(AstVisitAction.Continue);
                }

                if (!(methodCallAst.Member is StringConstantExpressionAst stringConstantAst))
                {
                    return(AstVisitAction.Continue);
                }

                if (stringConstantAst.Value.Equals("new", StringComparison.OrdinalIgnoreCase))
                {
                    string typeName = typeExpressionAst.TypeName.FullName;

                    CorrectionExtent suggestedCorrection = CreateNewObjectCorrection(
                        _analyzedFilePath,
                        methodCallAst.Extent,
                        typeName,
                        methodCallAst.Arguments);

                    AddDiagnostic(methodCallAst, "constructor", "[type]::new()", "3,4", suggestedCorrection);

                    return(AstVisitAction.Continue);
                }

                return(AstVisitAction.Continue);
            }