microsoft / microsoft/CSS-Exchange

Extend CheckTokenTypeCasing to enforce lowercase Type token casing

Open
#2,572 1 comment 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Build Process Enhancement
Dominant language
PowerShell
Stars
1.3k
Forks
395
Avg merge
14h 7m
Merged PRs (30d)
5

Description

Summary

Our code formatter's CheckTokenTypeCasing check (.build/CodeFormatterChecks/CheckTokenTypeCasing.ps1) currently only inspects Operator and Keyword PowerShell token types. It does not inspect the Type token type, which means inconsistent casing of type accelerators and built-in .NET short-form names slips through the pipeline unnoticed.

Neither PSSA's PSUseCorrectCasing (as configured in PSScriptAnalyzerSettings.psd1) nor any of the other seven checks wired into Invoke-CodeFormatterOnFiles flag this either — verified by running the current settings against a file mixing [DateTime]/[datetime], [TimeSpan], [Math]/[math] (zero diagnostics).

Evidence

Discovered while reviewing PR #2571. Transport/Get-TerrlExternalRecipientEstimate.ps1 uses both spellings in the same 911-line file, and the same concept is spelled two different ways:

Lowercase (majority) PascalCase (nested wrapper)
L100, L103, L449, L450, L497 [datetime] L539, L542 [DateTime]
L387, L401 [math] L588 [Math]
L532 [TimeSpan], L533/L579/L595/L602 [DateTime], L453 [ScriptBlock]

The formatter, SpellCheck.ps1, and Pester all pass, so the mixed casing merges cleanly.

Proposed change

Extend CheckTokenTypeCasing.ps1 to accept Type as a third option in the -Type ValidateSet, then wire a new call into .build/Invoke-CodeFormatterOnFiles.ps1:

$errorCount += (CheckTokenTypeCasing $fileInfo $Save "Type") ? 1 : 0

Enforcement rule: for tokens with PSTokenType.Type whose Content matches a known type accelerator or built-in short type name (datetime, timespan, string, int, bool, guid, math, scriptblock, hashtable, pscustomobject, object, convert, char, byte, long, double, decimal, regex, xml, array, void, type, etc.), require the lowercase form. Fully-qualified .NET namespaces ([System.DateTime], [System.Collections.Generic.List[object]]) should be left alone — those retain their canonical framework casing.

-Save behavior: rewrite the token in place using the same offset/insert pattern the existing Operator/Keyword branches already use.

Acceptance criteria

  • CheckTokenTypeCasing's ValidateSet includes "Type".
  • Invoke-CodeFormatterOnFiles invokes the check with -Type Type.
  • Running the formatter against the reproducer (a script containing [DateTime], [TimeSpan], [Math]) reports errors without -Save and rewrites them to lowercase with -Save.
  • Fully-qualified type names ([System.Collections.Generic.List[object]], [System.StringComparer]) are left untouched.
  • A follow-up sweep PR normalizes existing offenders under Transport/, Shared/, Diagnostics/, etc.

Non-goals

  • Enforcing casing on fully-qualified .NET type names (that's already handled correctly by the framework and would produce large, noisy diffs).
  • Any change to PSScriptAnalyzerSettings.psd1.

Repro

@'
[DateTime]::UtcNow
[TimeSpan]::FromMinutes(5)
[Math]::Round(1.0, 1)
'@ | Set-Content -Path .\repro.ps1 -Encoding utf8BOM

. .build\Invoke-CodeFormatterOnFiles.ps1
Invoke-CodeFormatterOnFiles -FilePaths .\repro.ps1  # currently returns 0 errors

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Read .build/CodeFormatterChecks/CheckTokenTypeCasing.ps1 and .build/Invoke-CodeFormatterOnFiles.ps1, then run the supplied repro through Invoke-CodeFormatterOnFiles without -Save. Done means Type tokens are reported and lowercased with -Save, while fully qualified names remain unchanged; verify the acceptance examples and formatter output.

Written by the indexing model from the issue text.

Assessment

Tech stack
powershell
Domain
tooling
Issue type
Feature
Difficulty
3/5
Estimated time
1-2 days
Activity status
Quiet
Clarity
Clearly specified
Newbie friendliness
74/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.