/// <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); }
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); }
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); }
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); }
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; }
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); }