feature: Tier 3 custom Roslyn analyzers CX001–CX004 (#49, #46) - #95
Merged
Conversation
added 3 commits
July 4, 2026 14:43
First increment of the Tier 3 custom analyzers (#49, parent #46). Establishes the Confuser.Analyzers project (netstandard2.0 Roslyn analyzer) and wires it into every project via ConfuserEx.Common.targets as an analyzer reference. CX004 — flags Assembly.GetTypes()/Module.GetTypes() that are not guarded against ReflectionTypeLoadException (the cause of packer/plugin startup crashes). The analyzer resolves the invocation symbol and only fires for System.Reflection types, so dnlib's ModuleDef.GetTypes() (which returns TypeDef and never throws) is ignored. - Fixed the two real CX004 violations: PluginDiscovery.AddPlugins and ComponentDiscovery.LoadComponents now catch ReflectionTypeLoadException and keep the types that loaded. - Analyzer wired with SkipGetTargetFrameworkProperties + UndefineProperties so the netstandard2.0 analyzer attaches to all targets including net20. - 4 analyzer unit tests (fires on unguarded; silent when guarded by RTLE/Exception or on unrelated GetTypes()). Full solution builds clean with zero CX004 warnings. Remaining under #49 (follow-up): CX002 (unguarded Resolve*Def), CX003 (ResolveThrow audit). CX001's premise is stale — the listed call sites were refactored to a context-aware Import helper; the only host-reflection path left is that helper's fallback (Confuser.Protections/Utils.cs).
CX003 surfaces every call to a dnlib Resolve...Throw helper (ResolveThrow, ResolveTypeDefThrow, ResolveMethodDefThrow, ResolveFieldThrow) at Info severity — an awareness rule for spots that crash on unresolvable references. Info severity means no build noise (the ~34 existing intentional uses are not reported as warnings). 5 tests.
Completes the four Tier 3 analyzers. CX002 — flags a non-throwing ResolveTypeDef()/ResolveMethodDef() result that is dereferenced immediately with no null check (crashes on external/unresolvable references). Only genuine dereferences are flagged (x.ResolveTypeDef().Member / [i]); null-conditional access, assignment, return, and passing the result as an argument (e.g. to dnlib's null-tolerant SigComparer.Equals, as VTableAnalyzer does) are correctly not reported. No existing violations — pure prevention. CX001 — redesigned against the current code. The issue's original call sites were already refactored to a context-aware Import(context, Type, method) helper; the only remaining host-reflection path is that helper's last-resort fallback. CX001 now flags Import(...) whose argument is Type.GetMethod/GetConstructor/GetField/ GetProperty (host reflection → wrong-corlib reference). The single intentional fallback in Confuser.Protections/Utils.cs is isolated and suppressed with a documented pragma; new occurrences are flagged. 8 new analyzer tests (17 total). Full solution builds clean — zero CX diagnostics.
…slyn-analyzers # Conflicts: # Confuser2.sln
This was referenced Jul 4, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Implements the Tier 3 ConfuserEx-specific analyzers — all four rules — completing #49. With #46's Tier 1 (built-in analyzers) and Tier 2 (Roslynator) already wired, this also finishes #46.
Closes #49
Closes #46
New:
Confuser.AnalyzersprojectA netstandard2.0 Roslyn analyzer assembly wired into every project via
ConfuserEx.Common.targets(SkipGetTargetFrameworkProperties+UndefinePropertiesso it attaches even to the net20 runtime).The four rules
Assembly/Module.GetTypes()withoutReflectionTypeLoadExceptionhandlingResolve...ThrowauditResolveTypeDef()/ResolveMethodDef()result dereferenced without a null checkImport(Type.GetMethod/GetConstructor/...)— host-reflection import (wrong-corlib)Design notes (the issue was partly stale — verified against current code)
System.Reflectiontypes — dnlib'sModuleDef.GetTypes()(returns TypeDef, never throws) is correctly ignored.SigComparer.Equals— not a crash — so they are correctly not flagged (no false positive).Import(context, Type, method)helper. The only remaining host-reflection path is that helper's last-resort fallback, which CX001 now targets; it's isolated and suppressed with a documented pragma.Tests & verification
Develop PRs are gated, so nothing runs automatically; validated locally.