Skip to content

Commit 967e956

Browse files
committed
Merge pull request #242 from PowerShell/BugFixes
Take Bug fixes to Master
2 parents 76200c9 + c85bf65 commit 967e956

18 files changed

+195
-130
lines changed

Engine/Helper.cs

Lines changed: 28 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -219,6 +219,21 @@ item is TypeDefinitionAst
219219
return false;
220220
}
221221

222+
/// <summary>
223+
/// Given a commandast, checks whether it uses splatted variable
224+
/// </summary>
225+
/// <param name="cmdAst"></param>
226+
/// <returns></returns>
227+
public bool HasSplattedVariable(CommandAst cmdAst)
228+
{
229+
if (cmdAst == null || cmdAst.CommandElements == null)
230+
{
231+
return false;
232+
}
233+
234+
return cmdAst.CommandElements.Any(cmdElem => cmdElem is VariableExpressionAst && (cmdElem as VariableExpressionAst).Splatted);
235+
}
236+
222237
/// <summary>
223238
/// Given a commandast, checks whether positional parameters are used or not.
224239
/// </summary>
@@ -237,6 +252,11 @@ public bool PositionalParameterUsed(CommandAst cmdAst)
237252
IEnumerable<CommandParameterSetInfo> scriptBlocks = null;
238253
bool hasScriptBlockSet = false;
239254

255+
if (HasSplattedVariable(cmdAst))
256+
{
257+
return false;
258+
}
259+
240260
if (commandInfo != null && commandInfo.CommandType == System.Management.Automation.CommandTypes.Cmdlet)
241261
{
242262
try
@@ -286,19 +306,19 @@ public bool PositionalParameterUsed(CommandAst cmdAst)
286306
}
287307
else
288308
{
289-
//Skip if splatting "@" is used
290-
if (ceAst is VariableExpressionAst)
291-
{
292-
if ((ceAst as VariableExpressionAst).Splatted)
293-
{
294-
continue;
295-
}
296-
}
297309
arguments += 1;
298310
}
299311
}
300312
}
301313

314+
// if not the first element in a pipeline, increase the number of arguments by 1
315+
PipelineAst parent = cmdAst.Parent as PipelineAst;
316+
317+
if (parent != null && parent.PipelineElements.Count > 1 && parent.PipelineElements[0] != cmdAst)
318+
{
319+
arguments += 1;
320+
}
321+
302322
return arguments > parameters;
303323
}
304324

Engine/SpecialVars.cs

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,8 @@ internal class SpecialVars
3434
internal const string PSScriptRoot = "PSScriptRoot";
3535
internal const string PSCommandPath = "PSCommandPath";
3636
internal const string ExecutionContext = "ExecutionContext";
37+
internal const string Matches = "Matches";
38+
internal const string PSVersionTable = "PSVersionTable";
3739

3840
internal static readonly string[] InitializedVariables;
3941

@@ -63,7 +65,9 @@ static SpecialVars()
6365
MyInvocation,
6466
PSScriptRoot,
6567
PSCommandPath,
66-
ExecutionContext
68+
ExecutionContext,
69+
Matches,
70+
PSVersionTable
6771
};
6872
internal static readonly Type[] AutomaticVariableTypes = new Type[]
6973
{
@@ -76,7 +80,9 @@ static SpecialVars()
7680
/* MyInvocation */ typeof(InvocationInfo),
7781
/* PSScriptRoot */ typeof(string),
7882
/* PSCommandPath */ typeof(string),
79-
/* ExecutionContext */ typeof(EngineIntrinsics),
83+
/* ExecutionContext */ typeof(EngineIntrinsics),
84+
/* Matches */ typeof(System.Collections.Hashtable),
85+
/* PSVersionTable */ typeof(System.Collections.Hashtable)
8086
};
8187

8288

Rules/AvoidPositionalParameters.cs

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -47,8 +47,23 @@ public IEnumerable<DiagnosticRecord> AnalyzeScript(Ast ast, string fileName)
4747
if (Helper.Instance.GetCommandInfo(cmdAst.GetCommandName()) != null
4848
&& Helper.Instance.PositionalParameterUsed(cmdAst))
4949
{
50-
yield return new DiagnosticRecord(string.Format(CultureInfo.CurrentCulture, Strings.AvoidUsingPositionalParametersError, cmdAst.GetCommandName()),
51-
cmdAst.Extent, GetName(), DiagnosticSeverity.Warning, fileName, cmdAst.GetCommandName());
50+
PipelineAst parent = cmdAst.Parent as PipelineAst;
51+
52+
if (parent != null && parent.PipelineElements.Count > 1)
53+
{
54+
// raise if it's the first element in pipeline. otherwise no.
55+
if (parent.PipelineElements[0] == cmdAst)
56+
{
57+
yield return new DiagnosticRecord(string.Format(CultureInfo.CurrentCulture, Strings.AvoidUsingPositionalParametersError, cmdAst.GetCommandName()),
58+
cmdAst.Extent, GetName(), DiagnosticSeverity.Warning, fileName, cmdAst.GetCommandName());
59+
}
60+
}
61+
// not in pipeline so just raise it normally
62+
else
63+
{
64+
yield return new DiagnosticRecord(string.Format(CultureInfo.CurrentCulture, Strings.AvoidUsingPositionalParametersError, cmdAst.GetCommandName()),
65+
cmdAst.Extent, GetName(), DiagnosticSeverity.Warning, fileName, cmdAst.GetCommandName());
66+
}
5267
}
5368
}
5469
}

Rules/ScriptAnalyzerBuiltinRules.csproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@
7575
<Compile Include="MissingModuleManifestField.cs" />
7676
<Compile Include="PossibleIncorrectComparisonWithNull.cs" />
7777
<Compile Include="ProvideCommentHelp.cs" />
78-
<Compile Include="ProvideVerboseMessage.cs" />
78+
<Compile Include="UseVerboseMessageInDSCResource.cs" />
7979
<Compile Include="Strings.Designer.cs">
8080
<AutoGen>True</AutoGen>
8181
<DesignTime>True</DesignTime>

Rules/Strings.Designer.cs

Lines changed: 37 additions & 46 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Rules/Strings.resx

Lines changed: 8 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -276,17 +276,14 @@
276276
<data name="SourceName" xml:space="preserve">
277277
<value>PS</value>
278278
</data>
279-
<data name="ProvideVerboseMessageDescription" xml:space="preserve">
280-
<value>Checks that Write-Verbose is called at least once in every cmdlet or script. This is in line with the PowerShell best practices.</value>
279+
<data name="UseVerboseMessageInDSCResourceDescription" xml:space="preserve">
280+
<value>It is a best practice to emit informative, verbose messages in DSC resource functions. This helps in debugging issues when a DSC configuration is executed.</value>
281281
</data>
282-
<data name="ProvideVerboseMessageErrorFunction" xml:space="preserve">
283-
<value>There is no call to Write-Verbose in the function ‘{0}’.</value>
282+
<data name="UseVerboseMessageInDSCResourceErrorFunction" xml:space="preserve">
283+
<value>There is no call to Write-Verbose in DSC function ‘{0}’. If you are using Write-Verbose in a helper function, suppress this rule application.</value>
284284
</data>
285-
<data name="ProvideVerboseMessageCommonName" xml:space="preserve">
286-
<value>Verbose</value>
287-
</data>
288-
<data name="ProvideVerboseMessageScript" xml:space="preserve">
289-
<value>There is no call to Write-Verbose in the script.</value>
285+
<data name="UseVerboseMessageInDSCResourceCommonName" xml:space="preserve">
286+
<value>Use verbose message in DSC resource</value>
290287
</data>
291288
<data name="MissingModuleManifestFieldDescription" xml:space="preserve">
292289
<value>Some fields of the module manifest (such as ModuleVersion) are required.</value>
@@ -459,8 +456,8 @@
459456
<data name="MissingModuleManifestFieldName" xml:space="preserve">
460457
<value>MissingModuleManifestField</value>
461458
</data>
462-
<data name="ProvideVerboseMessageName" xml:space="preserve">
463-
<value>ProvideVerboseMessage</value>
459+
<data name="UseVerboseMessageInDSCResourceName" xml:space="preserve">
460+
<value>UseVerboseMessageInDSCResource</value>
464461
</data>
465462
<data name="CommandNotFoundCommonName" xml:space="preserve">
466463
<value>Command Not Found</value>

Rules/UseCmdletCorrectly.cs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,12 @@ private bool IsMandatoryParameterExisted(CommandAst cmdAst)
9292
return true;
9393
}
9494

95+
// ignores if splatted variable is used
96+
if (Helper.Instance.HasSplattedVariable(cmdAst))
97+
{
98+
return true;
99+
}
100+
95101
// Gets parameters from command elements.
96102
ceAsts = cmdAst.CommandElements.Where<CommandElementAst>(foundParamASTs);
97103

Rules/UseDeclaredVarsMoreThanAssignments.cs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,8 +35,7 @@ public IEnumerable<DiagnosticRecord> AnalyzeScript(Ast ast, string fileName)
3535
{
3636
if (ast == null) throw new ArgumentNullException(Strings.NullAstErrorMessage);
3737

38-
IEnumerable<Ast> assignmentAsts = ast.FindAll(testAst => testAst is AssignmentStatementAst, true);
39-
IEnumerable<Ast> assingmentVarAsts;
38+
IEnumerable<Ast> assignmentAsts = ast.FindAll(testAst => testAst is AssignmentStatementAst, true);
4039
IEnumerable<Ast> varAsts = ast.FindAll(testAst => testAst is VariableExpressionAst, true);
4140
IEnumerable<Ast> varsInAssignment;
4241

0 commit comments

Comments
 (0)