|
| 1 | +<# |
| 2 | +.SYNOPSIS |
| 3 | + Builds samples/SampleUnityCode and asserts it produces exactly the expected OPL001 warnings. |
| 4 | +
|
| 5 | +.DESCRIPTION |
| 6 | + The sample is the end-to-end check that the analyzer loads from a ProjectReference and reports |
| 7 | + through a real compilation, not just through the test harness. This script rebuilds it, collects |
| 8 | + every distinct OPL001 warning from the build output, and compares them against the list below. |
| 9 | +
|
| 10 | + A diagnostic is identified by the allocated expression and the enclosing method, as they appear in |
| 11 | + the message, rather than by line and column, so reformatting the sample does not break the check. |
| 12 | + The comparison is exact: a missing warning (regression) and an unexpected one (false positive, for |
| 13 | + example in Start or in a class that is not a MonoBehaviour) both fail. |
| 14 | +
|
| 15 | +.PARAMETER Configuration |
| 16 | + Build configuration. Defaults to Release. |
| 17 | +
|
| 18 | +.PARAMETER NoDependencies |
| 19 | + Rebuild only the sample and reuse the analyzer assemblies already built. CI passes this after the |
| 20 | + solution build; locally, leave it off so the analyzer is built first. |
| 21 | +#> |
| 22 | +[CmdletBinding()] |
| 23 | +param( |
| 24 | + [string]$Configuration = 'Release', |
| 25 | + [switch]$NoDependencies |
| 26 | +) |
| 27 | + |
| 28 | +Set-StrictMode -Version Latest |
| 29 | +$ErrorActionPreference = 'Stop' |
| 30 | + |
| 31 | +# One entry per OPL001 warning in samples/SampleUnityCode/SampleBehaviour.cs: '<allocation> in <method>'. |
| 32 | +$expected = @( |
| 33 | + 'System.Collections.Generic.List<int> in Update' |
| 34 | + 'List<string> in Update' |
| 35 | + 'Instantiate in Update' |
| 36 | + 'int[10] in FixedUpdate' |
| 37 | +) |
| 38 | + |
| 39 | +$repoRoot = Split-Path -Parent $PSScriptRoot |
| 40 | +$sampleProject = Join-Path $repoRoot 'samples/SampleUnityCode/SampleUnityCode.csproj' |
| 41 | + |
| 42 | +# --no-incremental forces the compiler to run, so warnings are reported even when the sample is |
| 43 | +# already up to date. -warnaserror matches CI; the sample exempts OPL001 in its project file. |
| 44 | +$buildArgs = @('build', $sampleProject, '-c', $Configuration, '--nologo', '--no-incremental', '-warnaserror', '-clp:NoSummary') |
| 45 | +if ($NoDependencies) { $buildArgs += '--no-dependencies' } |
| 46 | + |
| 47 | +Write-Host "dotnet $($buildArgs -join ' ')" |
| 48 | +$output = & dotnet @buildArgs 2>&1 | ForEach-Object { "$_" } |
| 49 | +$exitCode = $LASTEXITCODE |
| 50 | +$output | Write-Host |
| 51 | +if ($exitCode -ne 0) { throw "Sample build failed with exit code $exitCode." } |
| 52 | + |
| 53 | +# MSBuild can echo a warning more than once; key on file(line,col) to count each diagnostic once. |
| 54 | +$pattern = '^(?<location>.+?\(\d+,\d+\)): warning OPL001: ''(?<allocation>.+?)'' is allocated inside the frequently-called method ''(?<method>.+?)''\.' |
| 55 | +$byLocation = [ordered]@{} |
| 56 | +foreach ($line in $output) { |
| 57 | + $match = [regex]::Match($line, $pattern) |
| 58 | + if ($match.Success) { |
| 59 | + $byLocation[$match.Groups['location'].Value.Trim()] = "$($match.Groups['allocation'].Value) in $($match.Groups['method'].Value)" |
| 60 | + } |
| 61 | +} |
| 62 | +$actual = @($byLocation.Values) |
| 63 | + |
| 64 | +$missing = @($expected | Where-Object { $actual -notcontains $_ }) |
| 65 | +$unexpected = @($actual | Where-Object { $expected -notcontains $_ }) |
| 66 | + |
| 67 | +if ($missing.Count -gt 0 -or $unexpected.Count -gt 0 -or $actual.Count -ne $expected.Count) { |
| 68 | + $message = "Sample OPL001 warnings do not match. Expected $($expected.Count), found $($actual.Count)." |
| 69 | + if ($missing.Count -gt 0) { $message += "`n Missing:`n " + ($missing -join "`n ") } |
| 70 | + if ($unexpected.Count -gt 0) { $message += "`n Unexpected:`n " + ($unexpected -join "`n ") } |
| 71 | + throw $message |
| 72 | +} |
| 73 | + |
| 74 | +Write-Host "Sample produced the $($expected.Count) expected OPL001 warnings:" |
| 75 | +$expected | ForEach-Object { Write-Host " $_" } |
0 commit comments