ããã«ã¡ã¯ãHabrïŒ
å°ãåã
sidristijã® CLRiumã«ã³ãã¡ã¬ã³ã¹ã«è¡ããŸãããããã§ã¯ãMSVS 2015ã§CïŒãœãŒã¹ã³ãŒããåæããããã®éåžžã«ã·ã³ãã«ã§äŸ¿å©ãªæ¹æ³ãèŠãŸããã
ã¿ã¹ã¯ã¯ãç§ãåå ããŠãããããžã§ã¯ãããååŸãããŸããåç
§åã®ååŒæ°ã«ã¯ãNotNull屿§ãŸãã¯CanBeNull屿§ãå¿
èŠã§ãïŒ
ReSharperã§ã¯ã䜿çšããŸã ïŒã ãã¡ãããå®éã«ã¯ããããžã§ã¯ãèªäœã§ã¯ã屿§ã¯ãã§ãã¯ã®äžéšã«ãããŸããããããã¯å±æ§ãå¿
é ã§ããããšã劚ãããã®ã§ã¯ãããŸããã ã¡ãœãããŸãã¯ã³ã³ã¹ãã©ã¯ã¿ãŒã«å¿
èŠãªå±æ§ãå«ãŸããŠããªãå Žåãã¢ã»ã³ããªããã§ãã¯ããŠã¯ã©ãã·ã¥ãããã¹ããæ¢ã«ãããŸãããéçºè
ã¯ãããã眮ãã®ãå¿ããããšãããããããã«ãã®ã¯ã©ãã·ã¥ãã³ãŒãã®æŽæ°ãªã©ã«ã€ãªãããŸãã ããã§ãVisual StudioãšReSharperãã³ãŒããããŸãè¯ããªããšããèŠåãåºããšãæéãšç¥çµãç¯çŽã§ããŸã...
å®éãæ°ããã¹ã¿ãžãªã§ã¯ããããå¯èœã«ãªããŸãïŒ ããã«ãç¬èªã®ãã§ãã¯ãè¡ãããšã¯éçŸå®çã§ãã
ãœãŒã¹ã³ãŒãã¯ãã¡ãã«ãããŸã ã
ãã®ããããŸãã¯
Microsoft Visual Studio 2015ãããŠã³ããŒãããŠããå¿
èŠããããŸãã éåžžã«éæšæºã®ç¿»èš³ã§ããã·ã¢èªçãæ¢ããŠããŠã³ããŒãããªãã£ããããèšèªãæ
éã«éžæããããšããå§ãããŸãã
次ã«ãMSVSã.NET Compiler Platform SDK Templatesãã®æ¡åŒµæ©èœãããŠã³ããŒãããå¿
èŠããããŸãïŒ
詳现ã¯ãã¡ã ã
Ordosã«æè¬ã
ãŸã ïŒã
次ã«ãã³ãŒãã¢ãã©ã€ã¶ãŒã®ãããžã§ã¯ããäœæããŸãã

ãã®çµæãã¹ã¿ãžãªã¯3ã€ã®ãããžã§ã¯ããäœæããŸããäœæ¥ãã©ããããã¹ããããã³vsixæ¡åŒµæ©èœã®ç¹å¥ãªãããžã§ã¯ãã§ãã æåã®ãããžã§ã¯ãã¯ãã¢ãã©ã€ã¶ãŒãå®è£
ããŠã³ãŒãä¿®æ£ãäœæããããã«å¿
èŠã§ããã€ãŸããã¹ã¿ãžãªã§ä¿®æ£ãææ¡ããããã³ããã衚瀺ãããŸãã ããã±ãŒãžãé
åžããã«ã¯ãvsixæ¡åŒµæ©èœãšnugetã®2ã€ã®æ¹æ³ããããŸãã 1ã€ç®ã§ã¯ããããžã§ã¯ãã«åœ±é¿ãäžããããšãªããçŸåšã®ã³ã³ãã¥ãŒã¿ãŒã«Visual Studioã®ãã§ãã¯ãã€ã³ã¹ããŒã«ã§ããŸãã 2çªç®ã®æ¹æ³ã§ã¯ãéçºäžïŒããã³ä»»æã®ã³ã³ãã¥ãŒã¿ãŒã§nugetããã±ãŒãžãããŠã³ããŒããããïŒããã«ãäžïŒVisual Studioãã€ã³ã¹ããŒã«ãããŠããªãå Žåã§ãïŒã«ã³ãŒãã確èªã§ããŸããããã¯Visual Studioã®ä»¥åã®ãªãªãŒã¹ã§ãæ©èœããŸãã nugetããã±ãŒãžãäœæããã«ã¯ãnuspecãã¡ã€ã«ãšããã€ãã®ã¹ã¯ãªããã§ååã§ãããvsixæ¡åŒµæ©èœçšã®è¿œå ãããžã§ã¯ããäœæãããŸãïŒããã§ã¯äŸãšããŠã®ã¿ç€ºããŸãïŒã
ãã¹ããããžã§ã¯ããè峿·±ããã®ã§ããVisualStudioãåå¥ã«èµ·åããã«ã¢ãã©ã€ã¶ãŒããã¹ãããã³ãããã°ã§ããŸãã CïŒãã¡ã€ã«ãäœæããã³ã³ãã€ã©ã«ããŒãããã ãã§ãèŠå/ãšã©ãŒãªã¹ããè¿ãããŸãïŒ
æåã«ãVisual Studioã¯ãã³ãã¬ãŒãã¢ãã©ã€ã¶ãŒãäœæããŸãããã³ãã¬ãŒãã¢ãã©ã€ã¶ãŒã§ã¯ããã¹ãŠã®ã¿ã€ãã§å€§æåã®åœåèŠåãå¿
èŠã§ãã ãããŠããã¹ãã¯åœŒã«åºã¥ããŠããŸãã
åäœã倿Žããã«ã¯ãDiagnosticAnalyzerã®äžäœã¯ã©ã¹ã«æ¬¡ã®å€æŽãå ããŸãã
1. DiagnosticIdãç¬èªã®ãã®ã«å€æŽããŸãã ãããèŠåã®ããŒã§ãïŒStringåã䜿çšïŒã 圌ã¯ããã°ã©ããŒã«ãã£ãŠãšã©ãŒã®ãªã¹ãã«è¡šç€ºãããCodeFixã¯åœŒã«åå¿ãã屿§SuppressMessageã䜿çšããŸãã 誀ã£ãŠèª°ããšäº€å·®ããªãããã«ãããæ¬ç©ã®ååãéžæããã®ãæåã§ãã <package nuget name> _ <internal id>ïŒNullCheckAnalyzer_MethodContainsNullsãšããŠéžæããŸãã
2.次ã«ããã¹ãŠã®èª¬æãç¬èªã®ãã®ã«å€æŽããã®ãæé©ã§ããã¡ãœããTitleãMessageFormatãDescriptionãCategoryãåç
§ããŠãã ããã
3.次ã«ãInitializeã¡ãœããã§ãRegisterSymbolAction颿°ã®åŒæ°ã倿ŽããŸããåã§ã¯ãªãã¡ãœããã«å¿çããŸãã ã¡ãªã¿ã«ãç§ã®ç ç©¶ãš
Roslynã®
ãœãŒã¹ãã倿ãããšãSymbolKindã®å€ã®äžéšã¯ãŸã£ãããµããŒããããŠããŸããïŒã€ãŸãããã©ã¡ãŒã¿ãŒã«å¿çã§ããªããªã©ïŒã
3. AnalyzeSymbolã¡ãœãããå°ã倿ŽããŸãã
-å
¥ãå£ã§ç¢ºèªããããŒã¯ã³ãååŸããŸã
-ãšã©ãŒããšã«ãã³ã³ããã¹ãã«é¢ããæ
å ±ã远å ããå¿
èŠããããŸãã ã€ãŸãã1ã€ã®ã¡ãœããã«å¯ŸããŠãç°ãªãIDã§å¥œããªã ããšã©ãŒãèŠã€ããããšãã§ããŸãã
次ã®ã³ãŒãã倿ããŸãã
[DiagnosticAnalyzer(LanguageNames.CSharp)] public class NullCheckAnalyzer : DiagnosticAnalyzer { public const string ParameterIsNullId = "NullCheckAnalyzer_MethodContainsNulls"; // You can change these strings in the Resources.resx file. If you do not want your analyzer to be localize-able, you can use regular strings for Title and MessageFormat. internal static readonly LocalizableString Title = new LocalizableResourceString(nameof(Resources.AnalyzerTitle), Resources.ResourceManager, typeof(Resources)); internal static readonly LocalizableString MessageFormat = new LocalizableResourceString(nameof(Resources.AnalyzerMessageFormat), Resources.ResourceManager, typeof(Resources)); internal static readonly LocalizableString Description = new LocalizableResourceString(nameof(Resources.AnalyzerDescription), Resources.ResourceManager, typeof(Resources)); internal const string Category = "Naming"; internal static DiagnosticDescriptor Rule = new DiagnosticDescriptor(ParameterIsNullId, Title, MessageFormat, Category, DiagnosticSeverity.Warning, isEnabledByDefault: true, description: Description); private static readonly ImmutableArray<DiagnosticDescriptor> supportedDiagnostics = ImmutableArray.Create(Rule); public override ImmutableArray<DiagnosticDescriptor> SupportedDiagnostics => supportedDiagnostics; public override void Initialize(AnalysisContext context) { context.RegisterSymbolAction(AnalyzeSymbol, SymbolKind.Method); } private static void AnalyzeSymbol(SymbolAnalysisContext context) { var methodSymbol = context.Symbol as IMethodSymbol; if (ReferenceEquals(null, methodSymbol) || methodSymbol.DeclaredAccessibility == Accessibility.Private) { return; } foreach (var parameter in ParametersGetter.GetParametersToFix(methodSymbol)) { var type = methodSymbol.ContainingType; // For all such symbols, produce a diagnostic. var diagnostic = Diagnostic.Create(Rule, parameter.Locations[0], methodSymbol.Name, type.Name, parameter.Name); context.ReportDiagnostic(diagnostic); } } }
ããã§ãå°ããªã¢ãã©ã€ã¶ãŒã¯æ¢ã«Visual Studioã§ãšã©ãŒãã¹ããŒããŸãã ãã¹ãããã«ã¯ããã¹ããå®è¡ããŸãã ãã€ã¯ããœããã¯ã空ã®ãã¡ã€ã«ãæ£ããããšã確èªããããšãšã蚺æãšä¿®æ£ãæ£ããæ©èœããããšã確èªããããšã®2ã€ãæ
éã«äœæããŸããã ãŸã ã³ãŒãä¿®æ£ãè¡ã£ãŠããªããããæåã®ãã®ã¯æ£ããå®äºãã2çªç®ã®ãã®ã¯å€±æããŸãã
ç§ã¯ããã«ã³ãŒãä¿®æ£ã詊ã¿ãŸãããããã®ãããªåçŽãªä¿®æ£ã§ãããããã»ã©ç°¡åã«è§£æ±ºã§ããªããã¥ã¢ã³ã¹ãæ¢ã«å«ãŸããŠããããšã«æ°ä»ããŸããã
-ã©ã®ããŒã ã¹ããŒã¹ããNotNull屿§ã远å ããŸããïŒ Resharperããã ãããŠãããã€ãã®ãªãã·ã§ã³ãããå ŽåïŒããªãã®å±æ§ãšResharperããã®ããã±ãŒãžïŒ
-䜿çšããŠè¿œå ããæ¹æ³ïŒåå空éå
ããŸãã¯ãã¡ã€ã«ã®äžã«ïŒ è¡çªã¯ãããŸããïŒ ããããããšã€ãªã¢ã¹ãç»é²ããæ¹ãè¯ãã§ããããïŒ
-屿§ãæã€ã¢ã»ã³ããªãžã®ãªã³ã¯ããªãå Žåã¯ãããã远å ããå¿
èŠããããŸãããã©ã®ãããªã«ãŒã«ã§ããïŒ æåã®ãã®ãååŸããããnugetããããŠã³ããŒãããŠã¿ãŸããïŒ ãŸãã¯äŒæ¥ã®ãã²ãããªããžããªããïŒ
ããã€ãã®ä¿®æ£ã詊ã¿ãåŸãç§ã¯ããã«æ°ä»ããŸããïŒ
1.åäœããŸãã Roslynã¯å®éã«å±æ§ã远å ããçµæãã³ã³ãã€ã«ããŸãã
2.ã¢ã«ãŽãªãºã ã¯éåžžã«åçŽã§ããå¿
èŠãª* SyntaxèŠçŽ ãèŠã€ããSyntaxFactoryã䜿çšããŠæ£ãããã®ãäœæããReplaceNodeãåŒã³åºãå¿
èŠããããŸãã
3.æ£ããã³ãŒãä¿®æ£ã¯ãäžèŠããã»ã©ç°¡åã§ã¯ãããŸããã ãŸããåé¡ã®ãã解決çãææ¡ãã代ããã«ãããã°ã©ããŒã«èªåã§ä¿®æ£ããããã«äŸé Œããããšããå§ãããŸãã
ã¢ãã©ã€ã¶ãŒããã¹ãããã«ã¯ãNugetããã±ãŒãžãã€ã³ã¹ããŒã«ããã ãã§ãïŒã€ãŸããããã±ãŒãžãããŒãžã£ãŒã³ã³ãœãŒã«ã§ã³ãã³ãInstall-Package NullCheckAnalyzerãå
¥åããŸãïŒã ãã ããã»ãšãã©ã®å Žåãæåã«PowerShellã¹ã¯ãªããã«ãšã©ãŒãå«ãŸãããããã³ã³ãã€ã«ããããã±ãŒãžã¯æ©èœããŸãããäœããã®çç±ã§ãã¢ãã©ã€ã¶ãŒã§dllãã¹ã«ãCïŒããµããã©ã«ããŒã远å ãããŸãã ãããã£ãŠããããã®è¡ã¯
ããã§è¡ãããã«å€æŽããã®ãæé©
ã§ã ã ãããã®æé ã®åŸãnugetããã±ãŒãžã®æºåãã§ããŸãããnuget.orgã«ã¢ããããŒãããŠããããžã§ã¯ãã«è¿œå ã§ããŸãã
ãããŠãMicrosoft Visual Studio 2015ã§ã¯æ¬¡ã®ããã«ãªããŸãã

ãã®çµæãåºåã§ã¯æ¡åŒµåãååŸãããŸãã
1. Nugetãä»ããŠæ¥ç¶ããã³æŽæ°ãã
2.æžã蟌ã¿ããã³ã³ã³ãã€ã«äžã«ã³ãŒãããã§ãã¯ããŸãïŒMSVSãªããå«ãïŒ
3.ç°¡åãã€è¿
éã«æžãããŠãããããäŒæ¥ã§ã®å¹³åçãªãã«ãªã¯ãšã¹ãã®ã¬ãã¥ãŒã«æéãããã
æåŸã«ãããã€ãã®ãã³ãïŒ
1.ã芧ã®ãšãããMicrosoftã¯äžå€åã奜ã¿ãŸããã ãããã£ãŠãã»ãšãã©ã®ã³ãŒãä¿®æ£ã³ã³ã¹ãã©ã¯ããäºåã«äœæããŠããããªã³ã¯ãæäŸããã ãã§ãã
2.ãã¹ãããã»ã¹ã§ã¯ã1ã€ã®ãã¡ã€ã«ã®ã¿ãç°¡åã«ç¢ºèªã§ãããããéšåã¯ã©ã¹ããã®ä»ã®ãã«ããã¡ã€ã«ãã¶ã€ã³ã®ãªãã·ã§ã³ãå
·äœçã«æäŸããããšããå§ãããŸã
3. Roslynã®ãªãªãŒã¹ããŒãžã§ã³ã¯ãŸã ãªããããAPIã¯è¥å¹²å€æŽãããå¯èœæ§ããããŸãã ãã§ã«ã
äžéšã®Stackoverflowã®åçã«ã¯å€ãAPIãã³ãããããŸãã
4. Ordosã¯ã
åæ§ã®èª¬æãå«ãã€ã³ã¿ãŒãããäžã®ããŒãžãææ¡ããŸããã