Skip to content

Commit 3eb0bbf

Browse files
authored
[CI Example Analyzer] Extract code without codeRegex (Azure#18891)
* abandon codeRegex * fix prompt regex * fix MissingOutput error * Fix bug for new-object typename
1 parent 817b5b2 commit 3eb0bbf

File tree

2 files changed

+32
-106
lines changed

2 files changed

+32
-106
lines changed

tools/StaticAnalysis/ExampleAnalyzer/AnalyzeRules/ParameterNameAndValue.psm1

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -169,10 +169,10 @@ function Measure-IsTypeMatched{
169169
}
170170
$Converter = [System.ComponentModel.TypeDescriptor]::GetConverter($ExpectedType)
171171
if ($ActualType -eq $ExpectedType -or
172-
$ActualType.GetInterfaces().Contains($ExpectedType) -or
173-
$ExpectedType.GetInterfaces().Contains($ActualType) -or
174-
$ActualType.IsSubclassOf($ExpectedType) -or
175-
$Converter.CanConvertFrom($ActualType)) {
172+
$ActualType.GetInterfaces().Contains($ExpectedType) -or
173+
$ExpectedType.GetInterfaces().Contains($ActualType) -or
174+
$ActualType.IsSubclassOf($ExpectedType) -or
175+
$Converter.CanConvertFrom($ActualType)) {
176176
return $true
177177
}
178178
return $false
@@ -231,9 +231,11 @@ function Get-AssignedParameterExpression {
231231
if($CommandElement_Copy.CommandElements[0].Extent.Text -eq "New-Object"){
232232
if($CommandElement_Copy.CommandElements[1].Extent.Text -eq "-TypeName"){
233233
$TypeName = $CommandElement_Copy.CommandElements[2].Extent.Text -replace "`""
234+
$TypeName = $TypeName -replace "'"
234235
}
235236
else{
236-
$TypeName = $CommandElement_Copy.CommandElements[1].Extent.Text
237+
$TypeName = $CommandElement_Copy.CommandElements[1].Extent.Text -replace "`""
238+
$TypeName = $TypeName -replace "'"
237239
}
238240
$OutputType = $TypeName -as [Type]
239241
$OutputTypes = @() + $OutputType

tools/StaticAnalysis/ExampleAnalyzer/utils.ps1

Lines changed: 25 additions & 101 deletions
Original file line numberDiff line numberDiff line change
@@ -109,84 +109,25 @@ function Get-ExamplesDetailsFromMd {
109109
if ($description -ne "") {
110110
$exampleDescriptions += $description
111111
}
112-
113-
# If there is no ```output``` split codelines and outputlines
114-
if ($exampleOutputBlocks.Count -eq 0) {
115-
foreach ($exampleCodeBlock in $exampleCodeBlocks) {
116-
$codeRegex = "(\n|\r\n)("+
117-
"(.*ForEach-Object {((.*(\n|\r\n))|(\w*=.*))*\s*})|"+
118-
"((.*[A-Za-z]\w+-[A-Za-z]\w+\s*(``(\n|\r\n))?)((\s*-.*``(\n|\r\n))*(.*@{((.*(\n|\r\n))|(\w*=.*))*\s*}\s*``?)+)+(?=\n|\r\n))|"+
119-
"((([A-Za-z \t])*(PS|[A-Za-z]:)(\w|[\\/\[\].\- ])*(>|>)+( PS)*)*[ \t]*((([A-Za-z]\w+-[A-Za-z]\w+\b(.ps1)?(?!(-| +\w)))|(" +
120-
"(@?\((?>\((?<pair>)|[^\(\)]+|\)(?<-pair>))*(?(pair)(?!))\) *[|.-] *\w)|" + # match ()
121-
"(\[(?>\[(?<pair>)|[^\[\]]+|\](?<-pair>))*(?(pair)(?!))\]\$)|" + # match []
122-
"((\$\w*\s*=.*)?@{(?>{(?<pair>)|[^{}]+|}(?<-pair>))*(?(pair)(?!))})|" + # match @{}
123-
"('(?>'(?<pair>)|[^']+|'(?<-pair>))*(?(pair)(?!))' *[|.-] *\w)|" + # match ''
124-
"((?<!``)`"(?>(?<!``)`"(?<pair>)|[\s\S]|(?<!``)`"(?<-pair>))*(?(pair)(?!))(?<!``)`" *[|.-] *\w)|" + # match ""
125-
"(\$\w*\s*=.*)?(@`"\s*(\n|\r\n)?(\{\s*)?)(.*(\n|\r\n))*((\s*\})?\s*(\n|\r\n)?`"@)|"+ # match @" "@
126-
"\$))(?!\.)([\w-~``'`"$= \t:;<>@()\[\]{},.+*/|\\&!?%#]*[``|][ \t]*(\n|\r\n)?)*([\w-~``'`"$= \t:;<>@()\[\]{},.+*/|\\&!?%#]*(?=\n|\r\n|#))))"+
127-
")"
128-
$exampleCodeLines = ($exampleCodeBlock.Value | Select-String -Pattern $codeRegex -CaseSensitive -AllMatches).Matches
129-
if ($exampleCodeLines.Count -eq 0) {
130-
$exampleCodes = @()
131-
$exampleOutputs = @()
132-
}
133-
else {
134-
for ($i = 0; $i -lt $exampleCodeLines.Count; $i++) {
135-
# If a codeline contains " :", it's not a codeline but an output line of "Format-List".
136-
if ($exampleCodeLines[$i].Value -notmatch " : *\w") {
137-
$exampleCodes += $exampleCodeLines[$i].Value.Trim()
138-
# Content before the first codeline, between codelines, and after the last codeline is output.
139-
if ($i -eq 0) {
140-
$startIndex = $exampleCodeBlock.Value.IndexOf("`n")
141-
$output = $exampleCodeBlock.Value.Substring($startIndex, $exampleCodeLines[$i].Index - $startIndex).Trim()
142-
if ($output -ne "" -and $output.Trim() -notlike "#*") {
143-
$exampleOutputs += $output
144-
}
145-
}
146-
$startIndex = $exampleCodeLines[$i].Index + $exampleCodeLines[$i].Length
147-
if ($i -lt $exampleCodeLines.Count - 1) {
148-
$nextStartIndex = $exampleCodeLines[$i + 1].Index
149-
}
150-
else {
151-
$nextStartIndex = $exampleCodeBlock.Value.LastIndexOf("`n")
152-
}
153-
# If an output line starts with "-", it's an incomplete codeline, but it should still be added to output.
154-
$output = $exampleCodeBlock.Value.Substring($startIndex, $nextStartIndex - $startIndex).Trim()
155-
if ($output -match "^-+\w") {
156-
$exampleOutputs += $output
157-
}
158-
elseif ($output -ne "" -and $output.Trim() -notlike "#*") {
159-
$exampleOutputs += $output
160-
}
161-
}
162-
}
163-
}
112+
# Extract code from the first "\n" to the last "\n"
113+
foreach ($exampleCodeBlock in $exampleCodeBlocks) {
114+
$code = $exampleCodeBlock.Value.Substring($exampleCodeBlock.Value.IndexOf("`n"), $exampleCodeBlock.Value.LastIndexOf("`n") - $exampleCodeBlock.Value.IndexOf("`n"))
115+
if ($code -ne ""-and $code -notmatch "{{ Add code here }}") {
116+
$exampleCodes += $code
164117
}
165118
}
166-
# If there is ```output```
167-
else {
168-
# Extract code from the first "\n" to the last "\n"
169-
foreach ($exampleCodeBlock in $exampleCodeBlocks) {
170-
$code = $exampleCodeBlock.Value.Substring($exampleCodeBlock.Value.IndexOf("`n"), $exampleCodeBlock.Value.LastIndexOf("`n") - $exampleCodeBlock.Value.IndexOf("`n")).Trim()
171-
if ($code -ne ""-and $code -notmatch "{{ Add code here }}") {
172-
$exampleCodes += $code
173-
}
174-
}
175-
# Extract output from the first "\n" to the last "\n"
176-
foreach ($exampleOutputBlock in $exampleOutputBlocks) {
177-
$output = $exampleOutputBlock.Value.Substring($exampleOutputBlock.Value.IndexOf("`n"), $exampleOutputBlock.Value.LastIndexOf("`n") - $exampleOutputBlock.Value.IndexOf("`n")).Trim()
178-
if ($output -ne "") {
179-
$exampleOutputs += $output
180-
}
119+
# Extract output from the first "\n" to the last "\n"
120+
foreach ($exampleOutputBlock in $exampleOutputBlocks) {
121+
$output = $exampleOutputBlock.Value.Substring($exampleOutputBlock.Value.IndexOf("`n"), $exampleOutputBlock.Value.LastIndexOf("`n") - $exampleOutputBlock.Value.IndexOf("`n")).Trim()
122+
if ($output -ne "") {
123+
$exampleOutputs += $output
181124
}
182125
}
183-
184126
# From the end of the last codeblock to the end is example description.
185127
if($null -ne $exampleOutputBlocks){
186128
$description = $exampleContent.SubString($exampleOutputBlocks[-1].Index + $exampleOutputBlocks[-1].Length).Trim()
187129
}
188130
else{
189-
190131
$description = $exampleContent.SubString($exampleCodeBlocks[-1].Index + $exampleCodeBlocks[-1].Length).Trim()
191132
}
192133
if ($description -ne "") {
@@ -198,7 +139,6 @@ function Get-ExamplesDetailsFromMd {
198139
Num = $exampleNumber + 1
199140
Title = $exampleTitle
200141
Codes = $exampleCodes
201-
CodeBlocks = $exampleCodeBlocks
202142
Outputs = $exampleOutputs
203143
OutputBlocks = $exampleOutputBlocks
204144
Description = ([string]$exampleDescriptions).Trim()
@@ -350,12 +290,13 @@ function Measure-SectionMissingAndOutputScript {
350290
else {
351291
foreach ($exampleDetails in $examplesDetails) {
352292
$exampleNumber = $exampleDetails.Num
293+
$exampleCodes = $exampleDetails.Codes
353294
$_missingExampleTitle = ($exampleDetails.Title | Select-String -Pattern "{{[A-Za-z ]*}}").Count
354295
$_missingExampleCode = ($exampleDetails.Codes | Select-String -Pattern "{{[A-Za-z ]*}}").Count
355296
$_missingExampleOutput = ($exampleDetails.Outputs | Select-String -Pattern "{{[A-Za-z ]*}}").Count
356297
$_missingExampleDescription = ($exampleDetails.Description | Select-String -Pattern "{{[A-Za-z ]*}}").Count
357-
$_needDeleting = ($exampleDetails.CodeBlocks | Select-String -Pattern "\n([A-Za-z \t\\:>])*(PS|[A-Za-z]:)(\w|[\\/\[\].\- ])*(>|&gt;)+( PS)*[ \t]*" -CaseSensitive).Count +
358-
($exampleDetails.CodeBlocks | Select-String -Pattern "(?<=[A-Za-z]\w+-[A-Za-z]\w+)\.ps1" -CaseSensitive).Count
298+
$_needDeleting = ($exampleDetails.Codes | Select-String -Pattern "`n([A-Za-z \t\\:>])*(PS|[A-Za-z]:)(\w|[\\/\[\].\- ])*(>|&gt;)+( PS)*[ \t]*" -CaseSensitive).Count +
299+
($exampleDetails.Codes | Select-String -Pattern "(?<=[A-Za-z]\w+-[A-Za-z]\w+)\.ps1" -CaseSensitive).Count
359300
switch ($exampleDetails) {
360301
{$exampleDetails.Title -eq "" -or $_missingExampleTitle -ne 0} {
361302
$missingExampleTitle ++
@@ -402,21 +343,6 @@ function Measure-SectionMissingAndOutputScript {
402343
}
403344
$results += $result
404345
}
405-
{$exampleDetails.OutputBlocks.Count -eq 0 -and $exampleDetails.Outputs.Count -ne 0} {
406-
$needSplitting++
407-
$result = [AnalysisOutput]@{
408-
Module = $Module
409-
Cmdlet = $Cmdlet
410-
Example = $exampleDetails.Num
411-
Description = "The output need to be split from example."
412-
RuleName = "NeedSplitting"
413-
Severity = $missingSeverity
414-
Extent = "$Module\help\$Cmdlet.md"
415-
ProblemID = 5051
416-
Remediation = "Split output from example."
417-
}
418-
$results += $result
419-
}
420346
{$exampleDetails.Description -eq "" -or $_missingExampleDescription -ne 0} {
421347
$missingExampleDescription++
422348
$result = [AnalysisOutput]@{
@@ -442,30 +368,28 @@ function Measure-SectionMissingAndOutputScript {
442368
RuleName = "NeedDeleting"
443369
Severity = $missingSeverity
444370
Extent = "$Module\help\$Cmdlet.md"
445-
ProblemID = 5052
371+
ProblemID = 5051
446372
Remediation = "Delete the prompt of example."
447373
}
448374
$results += $result
375+
$newCode = $exampleCodes -replace "`n([A-Za-z \t\\:>])*(PS|[A-Za-z]:)(\w|[\\/\[\].\- ])*(>|&gt;)+( PS)*[ \t]*", "`n"
376+
$newCode = $newCode -replace "(?<=[A-Za-z]\w+-[A-Za-z]\w+)\.ps1"
377+
$exampleCodes = $newCode
449378
}
450379
}
451380

452-
# Delete prompts
453-
$exampleCodes = $exampleDetails.Codes
454-
for ($i = $exampleCodes.Count - 1; $i -ge 0; $i--) {
455-
$newCode = $exampleDetails.Codes[$i] -replace "([A-Za-z \t\\:>])*(PS|[A-Za-z]:)(\w|[\\/\[\].\- ])*(>|&gt;)+( PS)*[ \t]*", ""
456-
$newCode = $newCode -replace "(?<=[A-Za-z]\w+-[A-Za-z]\w+)\.ps1", ""
457-
$exampleCodes[$i] = $newCode
458-
}
459381

460382
# Output example codes to "TempScript.ps1"
461383
if ($OutputScriptsInFile.IsPresent) {
462384
$cmdletExamplesScriptPath = "$OutputFolder\TempScript.ps1"
463-
$functionHead = "function $Module-$Cmdlet-$exampleNumber{"
464-
Add-Content -Path (Get-Item $cmdletExamplesScriptPath).FullName -Value $functionHead
465-
$exampleCodes = $exampleCodes -join "`n"
466-
Add-Content -Path (Get-Item $cmdletExamplesScriptPath).FullName -Value $exampleCodes
467-
$functionTail = "}`n"
468-
Add-Content -Path (Get-Item $cmdletExamplesScriptPath).FullName -Value $functionTail
385+
if($exampleCodes -ne $null){
386+
$exampleCodes = $exampleCodes.Trim()
387+
$functionHead = "function $Module-$Cmdlet-$exampleNumber{"
388+
Add-Content -Path (Get-Item $cmdletExamplesScriptPath).FullName -Value $functionHead
389+
Add-Content -Path (Get-Item $cmdletExamplesScriptPath).FullName -Value $exampleCodes
390+
$functionTail = "}`n"
391+
Add-Content -Path (Get-Item $cmdletExamplesScriptPath).FullName -Value $functionTail
392+
}
469393
}
470394
}
471395
}

0 commit comments

Comments
 (0)