@@ -183,27 +183,34 @@ public override AstVisitAction VisitInvokeMemberExpression(InvokeMemberExpressio
183
183
{
184
184
// Look for [typename]::new(...) and [typename]::$dynamicMethodName syntax
185
185
186
+ #if PSV7
187
+ if ( ! TargetsNonPS7 ( ) )
188
+ {
189
+ return AstVisitAction . Continue ;
190
+ }
191
+
192
+ if ( methodCallAst . NullConditional )
193
+ {
194
+ AddDiagnostic (
195
+ methodCallAst ,
196
+ "null-conditional method invocation" ,
197
+ "${x}?.Method()" ,
198
+ "3,4,5,6" ) ;
199
+ }
200
+ #endif
201
+
186
202
if ( ! _targetVersions . Contains ( s_v3 ) && ! _targetVersions . Contains ( s_v4 ) )
187
203
{
188
204
return AstVisitAction . Continue ;
189
205
}
190
206
191
207
if ( _targetVersions . Contains ( s_v3 ) && methodCallAst . Member is VariableExpressionAst )
192
208
{
193
- string message = string . Format (
194
- CultureInfo . CurrentCulture ,
195
- Strings . UseCompatibleSyntaxError ,
209
+ AddDiagnostic (
210
+ methodCallAst ,
196
211
"dynamic method invocation" ,
197
- methodCallAst . Extent . Text ,
212
+ "$x.$method()" ,
198
213
"3" ) ;
199
-
200
- _diagnosticAccumulator . Add ( new DiagnosticRecord (
201
- message ,
202
- methodCallAst . Extent ,
203
- _rule . GetName ( ) ,
204
- _rule . Severity ,
205
- _analyzedFilePath
206
- ) ) ;
207
214
}
208
215
209
216
if ( ! ( methodCallAst . Expression is TypeExpressionAst typeExpressionAst ) )
@@ -226,22 +233,7 @@ public override AstVisitAction VisitInvokeMemberExpression(InvokeMemberExpressio
226
233
typeName ,
227
234
methodCallAst . Arguments ) ;
228
235
229
- string message = string . Format (
230
- CultureInfo . CurrentCulture ,
231
- Strings . UseCompatibleSyntaxError ,
232
- "constructor" ,
233
- methodCallAst . Extent . Text ,
234
- "3,4" ) ;
235
-
236
- _diagnosticAccumulator . Add ( new DiagnosticRecord (
237
- message ,
238
- methodCallAst . Extent ,
239
- _rule . GetName ( ) ,
240
- _rule . Severity ,
241
- _analyzedFilePath ,
242
- ruleId : null ,
243
- suggestedCorrections : new [ ] { suggestedCorrection }
244
- ) ) ;
236
+ AddDiagnostic ( methodCallAst , "constructor" , "[type]::new()" , "3,4" , suggestedCorrection ) ;
245
237
246
238
return AstVisitAction . Continue ;
247
239
}
@@ -263,21 +255,7 @@ public override AstVisitAction VisitFunctionDefinition(FunctionDefinitionAst fun
263
255
return AstVisitAction . Continue ;
264
256
}
265
257
266
- string message = string . Format (
267
- CultureInfo . CurrentCulture ,
268
- Strings . UseCompatibleSyntaxError ,
269
- "workflow" ,
270
- "workflow { ... }" ,
271
- "6" ) ;
272
-
273
- _diagnosticAccumulator . Add (
274
- new DiagnosticRecord (
275
- message ,
276
- functionDefinitionAst . Extent ,
277
- _rule . GetName ( ) ,
278
- _rule . Severity ,
279
- _analyzedFilePath
280
- ) ) ;
258
+ AddDiagnostic ( functionDefinitionAst , "workflow" , "workflow { ... }" , "6,7" ) ;
281
259
282
260
return AstVisitAction . Continue ;
283
261
}
@@ -292,22 +270,12 @@ public override AstVisitAction VisitUsingStatement(UsingStatementAst usingStatem
292
270
return AstVisitAction . Continue ;
293
271
}
294
272
295
- string message = string . Format (
296
- CultureInfo . CurrentCulture ,
297
- Strings . UseCompatibleSyntaxError ,
273
+ AddDiagnostic (
274
+ usingStatementAst ,
298
275
"using statement" ,
299
276
"using ...;" ,
300
277
"3,4" ) ;
301
278
302
- _diagnosticAccumulator . Add (
303
- new DiagnosticRecord (
304
- message ,
305
- usingStatementAst . Extent ,
306
- _rule . GetName ( ) ,
307
- _rule . Severity ,
308
- _analyzedFilePath
309
- ) ) ;
310
-
311
279
return AstVisitAction . Continue ;
312
280
}
313
281
@@ -340,6 +308,145 @@ public override AstVisitAction VisitTypeDefinition(TypeDefinitionAst typeDefinit
340
308
}
341
309
#endif
342
310
311
+ #if PSV7
312
+ public override AstVisitAction VisitMemberExpression ( MemberExpressionAst memberExpressionAst )
313
+ {
314
+ if ( ! TargetsNonPS7 ( ) )
315
+ {
316
+ return AstVisitAction . Continue ;
317
+ }
318
+
319
+ if ( memberExpressionAst . NullConditional )
320
+ {
321
+ AddDiagnostic (
322
+ memberExpressionAst ,
323
+ "null-conditional member access" ,
324
+ "${x}?.Member" ,
325
+ "3,4,5,6" ) ;
326
+ }
327
+
328
+ return AstVisitAction . Continue ;
329
+ }
330
+
331
+ public override AstVisitAction VisitAssignmentStatement ( AssignmentStatementAst assignmentStatementAst )
332
+ {
333
+ if ( ! TargetsNonPS7 ( ) )
334
+ {
335
+ return AstVisitAction . Continue ;
336
+ }
337
+
338
+ if ( assignmentStatementAst . Operator == TokenKind . QuestionQuestionEquals )
339
+ {
340
+ AddDiagnostic ( assignmentStatementAst , "null-conditional assignment" , "$x ??= $y" , "3,4,5,6" ) ;
341
+ }
342
+
343
+ return AstVisitAction . Continue ;
344
+ }
345
+
346
+ public override AstVisitAction VisitBinaryExpression ( BinaryExpressionAst binaryExpressionAst )
347
+ {
348
+ if ( ! TargetsNonPS7 ( ) )
349
+ {
350
+ return AstVisitAction . Continue ;
351
+ }
352
+
353
+ if ( binaryExpressionAst . Operator == TokenKind . QuestionQuestion )
354
+ {
355
+ AddDiagnostic (
356
+ binaryExpressionAst ,
357
+ "null-coalescing operator" ,
358
+ "$x ?? $y" ,
359
+ "3,4,5,6" ) ;
360
+ }
361
+
362
+ return AstVisitAction . Continue ;
363
+ }
364
+
365
+ public override AstVisitAction VisitTernaryExpression ( TernaryExpressionAst ternaryExpressionAst )
366
+ {
367
+ if ( ! TargetsNonPS7 ( ) )
368
+ {
369
+ return AstVisitAction . Continue ;
370
+ }
371
+
372
+ var correction = new CorrectionExtent (
373
+ ternaryExpressionAst . Extent ,
374
+ $ "if ({ ternaryExpressionAst . Condition . Extent . Text } ) {{ { ternaryExpressionAst . IfTrue . Extent . Text } }} else {{ { ternaryExpressionAst . IfFalse . Extent . Text } }}",
375
+ _analyzedFilePath ) ;
376
+
377
+ AddDiagnostic (
378
+ ternaryExpressionAst ,
379
+ "ternary expression" ,
380
+ "<test> ? <exp1> : <exp2>" ,
381
+ "3,4,5,6" ,
382
+ correction ) ;
383
+
384
+ return AstVisitAction . Continue ;
385
+ }
386
+
387
+ public override AstVisitAction VisitPipelineChain ( PipelineChainAst statementChain )
388
+ {
389
+ if ( ! TargetsNonPS7 ( ) )
390
+ {
391
+ return AstVisitAction . Continue ;
392
+ }
393
+
394
+ AddDiagnostic (
395
+ statementChain ,
396
+ "pipeline chain" ,
397
+ "<pipeline1> && <pipeline2> OR <pipeline1> || <pipeline2>" ,
398
+ "3,4,5,6" ) ;
399
+
400
+ return AstVisitAction . Continue ;
401
+ }
402
+
403
+ private bool TargetsNonPS7 ( )
404
+ {
405
+ return _targetVersions . Contains ( s_v3 )
406
+ || _targetVersions . Contains ( s_v4 )
407
+ || _targetVersions . Contains ( s_v5 )
408
+ || _targetVersions . Contains ( s_v6 ) ;
409
+ }
410
+ #endif
411
+
412
+ private void AddDiagnostic (
413
+ Ast offendingAst ,
414
+ string syntaxName ,
415
+ string syntaxExample ,
416
+ string unsupportedVersions ,
417
+ CorrectionExtent correction = null )
418
+ {
419
+ string message = string . Format (
420
+ CultureInfo . CurrentCulture ,
421
+ Strings . UseCompatibleSyntaxError ,
422
+ syntaxName ,
423
+ syntaxExample ,
424
+ unsupportedVersions ) ;
425
+
426
+ if ( correction == null )
427
+ {
428
+ _diagnosticAccumulator . Add (
429
+ new DiagnosticRecord (
430
+ message ,
431
+ offendingAst . Extent ,
432
+ _rule . GetName ( ) ,
433
+ _rule . Severity ,
434
+ _analyzedFilePath ) ) ;
435
+
436
+ return ;
437
+ }
438
+
439
+ _diagnosticAccumulator . Add (
440
+ new DiagnosticRecord (
441
+ message ,
442
+ offendingAst . Extent ,
443
+ _rule . GetName ( ) ,
444
+ _rule . Severity ,
445
+ _analyzedFilePath ,
446
+ ruleId : null ,
447
+ new [ ] { correction } ) ) ;
448
+ }
449
+
343
450
private static CorrectionExtent CreateNewObjectCorrection (
344
451
string filePath ,
345
452
IScriptExtent offendingExtent ,
0 commit comments