èšäºã®æŠèŠïŒ
- éçºç°å¢ã®ã»ããã¢ãã
- äŸ1ïŒæãåçŽãªã¹ã¿ãæ¡åŒµ
- ãã©ã°ã€ã³ã®ã€ã³ã¹ããŒã«
- ãããã°ã®ãã³ã
- äŸ2ïŒRïŒAPIã䜿çšããã³ãŒãå€æŽ
- RïŒAPIã䜿çšãããã©ã°ã€ã³ã®æ©èœãã¹ã
ãã£ã¹ãïŒ
Visual Studio 2015
ReSharper Ultimate 10
ãã£ããã®äžã§ç§ãæåŸ ããå©å®³é¢ä¿è
1.éçºç°å¢ã®ã»ããã¢ãã
ã³ãŒããèšè¿°ããVisual Studioã®ã¡ã€ã³ã€ã³ã¹ã¿ã³ã¹ã®äœæ¥ã劚ããªãããã«ãå°æ¥ã®ãã©ã°ã€ã³çšã«å¥ã®ããšã³ã·ã¹ãã ããããã«æºåããã®ãæåã§ãã ããããããŠã³ããŒãããããšããå§ããŸã ããã§ãã¯ãã«ãã-æ¡åŒµèšºææ å ±ãåããRïŒUltimateã®ã¢ã»ã³ããªããã®ä»ã¯èªç¶ãšåãã§ãã
ãŸããVisual Studio Experimentalã€ã³ã¹ã¿ã³ã¹ãå¿ èŠã§ããããã¯ããŠã£ã³ããŠã®å Žæããã€ã³ã¹ããŒã«ãããæ¡åŒµæ©èœãŸã§ã®ãã¹ãŠã®ãŠãŒã¶ãŒèšå®ãå«ãäžçš®ã®ããããã¡ã€ã«ãã§ãïŒããã§ãïŒïŒã ãããã¡ã€ã«ã¯èšå®ã¬ãã«ã§æ£ç¢ºã«çžäºã«åé¢ãããŠãããStudioã®å®è¡å¯èœãã¡ã€ã«ã¯ã©ãã«ãã³ããŒãããŸããã VS2015ã§ã¯ãCreateExpInstance.exeãŠãŒãã£ãªãã£ã䜿çšããŠãããã¡ã€ã«ã管çã§ããŸãããããã«ç°¡åãªæ¹æ³ããããŸãã 以åã«ã€ã³ã¹ããŒã«ãããã§ãã¯ãã«ãã®ã€ã³ã¹ããŒã©ãŒãèµ·åããïŒãªãã·ã§ã³-å®éšãã€ãïŒã«ç§»åããŠãéçºããããã©ã°ã€ã³ã®ã€ã³ã¹ããŒã«ã«äœ¿çšãããæ°ãããããã¡ã€ã«ã®ååãå ¥åããŸããå·§åŠãªRïŒããã®ãããã¡ã€ã«ãäœæããããã«ã€ã³ã¹ããŒã«ããŸãã ããã§ããRïŒã®ç¬èªã®ããŒãžã§ã³ãå«ãåãããã¡ã€ã«ã«äžé£ã®æ¡åŒµæ©èœãã€ã³ã¹ããŒã«ããããšãã§ããŸããããã«ãããè€æ°ã®ããŒãžã§ã³ã®ãã©ã°ã€ã³ãäžåºŠã«ãã¹ãã§ããŸãã æ¢ã«è¿°ã¹ãããã«ããããã¡ã€ã«ã¯äºãã«ç¬ç«ããŠãããããVisual Studioã®äœæ¥ãããã¡ã€ã«ã¯åœ±é¿ãåããŸããã
æ°ãããããã¡ã€ã«ã§Studioãèµ·åããã«ã¯ã次ã®åœ¢åŒã®ã·ã§ãŒãã«ãããå¿ èŠã§ãã
ãXïŒ\ Microsoft Visual Studio 14.0 \ Common7 \ IDE \ devenv.exeã/ rootSuffix YourHive /ReSharper.Internal
ããã§ãYourHiveã¯ä»¥åã«äœæããããããã¡ã€ã«ã®ååã§ããã/ ReSharper.Internalãã©ã¡ãŒã¿ãŒã¯éçºã¢ãŒãã§RïŒãèµ·åãããã©ã°ã€ã³å ã§çæãããäŸå€ã®éç¥ãªã©ã®äŸ¿å©ãªæ©èœãæå¹ã«ããŸãã
2.äŸ1ïŒåçŽãªãã©ã°ã€ã³æ¡åŒµ
RïŒã¯ãã¯ã€ãã¯ãã£ãã¯ã¹ãã³ã³ããã¹ãã¢ã¯ã·ã§ã³ããªãã¡ã¯ã¿ãªã³ã°ãªã©ãã³ãŒããå€æŽããã³çæããããã®ããŸããŸãªæ¹æ³ãæäŸããŸãã Quick-Fixãå®è£ ããã®ãæãç°¡åã§ããããã«æããã®ã§ãããããå§ããŸãã ã¯ã€ãã¯ãã£ãã¯ã¹ã¯ãã䜿çšãããŠããªãå€æ°ãåé€ãããã³ã³ã¹ãã©ã¯ã¿ãŒããããããã£ãåæåããããªã©ãAlt + Enterã§ãããã¢ããããã¡ãã¥ãŒã«é»è²/èµ€è²ã®ã¢ã€ã³ã³ã§è¡šç€ºãããRïŒãŠãŒã¶ãŒã«ç¥ãããŠããã³ãã³ãã§ãã
ãã®ãããã¹ã¿ãžãªã®ã¡ã€ã³ã€ã³ã¹ã¿ã³ã¹ïŒå®éšçã§ã¯ãªãïŒãéããæ°ããã¯ã©ã¹ã©ã€ãã©ãªãããžã§ã¯ããäœæããŸãã RïŒSDKãã€ã³ã¹ããŒã«ããŸãã
ã€ã³ã¹ããŒã«ããã±ãŒãžJetBrains.ReSharper.SDK
RïŒãRïŒSDKãããã³äžäœäºææ§ã®ããŒãžã§ã³ã§ã¯ãªãããã®äžåš
å·çæç¹ã§ãJetBrains.ReSharper.SDKã®ææ°ãªãªãŒã¹ããŒãžã§ã³ã¯ããŒãžã§ã³10.0.20151101.194233ã§ãRïŒ10ã«å¯Ÿå¿ããŠããŸã ãJetBrainsã¯è£œåã®ã¡ãžã£ãŒããŒãžã§ã³ãšãã€ããŒããŒãžã§ã³éã®äºææ§ãæäŸããªããã ãSDK 9.1ã§ãã«ãããããã©ã°ã€ã³ã®åäœã¯RïŒ9.2ã§ã¯ä¿èšŒãããŸãããªã© 以éãSDK 10ã䜿çšãããŸããããã¯ãRïŒ10ã®ã¿ããµããŒãããRïŒ9.2ã§æ£ããã€ã³ã¹ããŒã«ããã³åäœã§ããªãããšãæå³ããŸãã åæã«ãSDK 9.2ã®èšäºã§èª¬æãããŠãããã¹ãŠã®ã³ãŒããåæ§ç¯ããããã®é害ããªããããã«ãã£ãŠRïŒ9.2ã§åäœãããã©ã°ã€ã³ãååŸã§ããŸã-æ€èšŒæžã¿ã§ãã
ãããžã§ã¯ãã«æ¬¡ã®ã¯ã©ã¹ãé 眮ããŸãããã
[QuickFix] public class SimpleFix : QuickFixBase { public SimpleFix(NotInitializedLocalVariableError error) { } protected override Action<ITextControl> ExecutePsiTransaction(ISolution solution, IProgressIndicator progress) { return null; } public override string Text => "SimpleFix"; public override bool IsAvailable(IUserDataHolder cache) { return true; } }
Quick-Fixã«ã¯ãSomeError / SomeWarningåã®å ¥åãã©ã¡ãŒã¿ãŒãæã€å°ãªããšã1ã€ã®é¡äŒŒããã³ã³ã¹ãã©ã¯ã¿ãŒãå¿ èŠã§ããããšã«æ³šæããŠãã ããã ãã©ã¡ãŒã¿ãŒã®ã¿ã€ãã«ãããããããããŠã³ã¡ãã¥ãŒã§äœ¿çšå¯èœãªQuick-Fixã³ãŒãã®ãšã©ãŒã決ãŸããŸãã åæåãããŠããªãããŒã«ã«å€æ°ã䜿çšãããšãQuick-Fixãå©çšå¯èœã«ãªããŸãã
RïŒSDKã¯ãJetBrains.ReSharper.Daemon.CSharp.Errorsåå空éã§äœ¿çšå¯èœãªæ°çŸã®ãšã©ãŒã¯ã©ã¹ãå®çŸ©ããŠããŸãã ã³ã³ãã€ã«ãšã©ãŒã«å¯Ÿå¿ããã¯ã©ã¹ã«ã¯ãååã«postfix ErrorããããéèŠã§ã¯ãªãããŸããŸãªæ¹åç¹-Warning postfixããããŸãã 次ã®ã»ã¯ã·ã§ã³å šäœã§ã¯ãQuick-Fixã®å±éã«èŠãã¿ãŸãã
3.ãã©ã°ã€ã³ã®ã€ã³ã¹ããŒã«
ãããžã§ã¯ãã«ãã1ã€ã®ã¯ã©ã¹ãè¿œå ããŸãã
[ZoneMarker] public class ZoneMarker { }
ãŸãŒã³ã¯ãããŒãžã§ã³9.0ã§å°å ¥ãããæ°ããRïŒSDKæ©èœã§ãããçŸåšãéçºäžã§ãã å«ãããŸãŒã³ã®å©ããåããŠãéçºäžã®æ¡åŒµæ©èœãRïŒãã©ãããã©ãŒã ã®ã©ã®è£œåã«åããããŠãããã瀺ãããŸãã 幞ããªããšã«ãä»ã®ãšããã¯ãã¹ã¿ãã¯ã©ã¹ã«éå®ããå¿ èŠããããŸãã
éèŠïŒZoneMarkerã¯ã以åã«äœæãããSimpleFixã¯ã©ã¹ãšåãåå空éã«ååšããå¿ èŠããããŸãã
次ã®ãã¥ã¢ã³ã¹ã¯ãRïŒ9+ã§ã®ãã©ã°ã€ã³ã®é åžãšã€ã³ã¹ããŒã«ãNuGetããã±ãŒãžãä»ããŠã®ã¿è¡ãããããšã§ãã æ£ããããã±ãŒãžãäœæããã«ã¯ãæ¡åŒµåã.nuspecã®ãã¡ã€ã«ãšæ¬¡ã®å 容ããããžã§ã¯ãã«è¿œå ããŸãã
<?xml version="1.0"?> <package> <metadata> <id>PaperSource.ReSharper.HelloWorld</id> <version>1.0.5</version> <authors>You</authors> <owners>You</owners> <requireLicenseAcceptance>false</requireLicenseAcceptance> <description> , id !</description> <tags>habrahabr.ru</tags> <dependencies> <dependency id="Wave" version="4.0" /> </dependencies> </metadata> <files> <file src="bin\Debug\PluginV10.dll" target="dotFiles\" /> <file src="bin\Debug\PluginV10.pdb" target="dotFiles\" /> </files> </package>
éèŠãªãã€ã³ãïŒ
1. Waveããã±ãŒãžãžã®äŸåãå¿ èŠã§ãã Waveã¯RïŒãã©ãããã©ãŒã ã®æ°ããé åžã¢ãã«ã§ãããRïŒã«å ããŠãdotPeekãdotTraceãªã©ãå«ãŸããŸãã
ReSharper 9.0-Wave 1.0;
ReSharper 9.1-Wave 2.0;
ReSharper 9.2-Wave 3.0;
ReSharper 10.0-Wave 4.0;
<dependency>ã¿ã°ã«ãªã¹ããããŠããªãããŒãžã§ã³ã®RïŒã®å Žåããã©ã°ã€ã³ã¯Extention Managerã«ååšããªããããã€ã³ã¹ããŒã«ã«äœ¿çšã§ããŸããã è€æ°ã®ããŒãžã§ã³ãæå®ããã«ã¯ã[AãBïŒãšãã圢åŒã®ã¬ã³ãŒãã䜿çšããå¿ èŠããããŸãããã[ãã¯ãå æ¬çããªã©ãæå³ããŸãã
2. <id>ã¿ã°ã§ç€ºããããã©ã°ã€ã³åã«ã¯ããããå«ããå¿ èŠããããŸãã ããã ãã§ãªããããã ãã§ãïŒ æšå¥šããã圢åŒã¯ãCompany.Packageãã§ãã
NuGet.exeãã€ã³ã¹ããŒã«ããããããã±ãŒãžãããŒãžã£ãŒã³ã³ãœãŒã«ãéãã次ã®ã³ãã³ããå®è¡ããŸãã
nugetããã¯ãPaperSource.ReSharper.HelloWorld \ package.nuspecã
å®æãã.nupkgãã¡ã€ã«ããœãªã¥ãŒã·ã§ã³ã®ãã©ã«ããŒã«è¡šç€ºãããŸãïŒãŸãã¯-OutputDirectoryãã©ã¡ãŒã¿ãŒã䜿çšããŠãå¿ èŠãªãã©ã«ããŒã«ããã±ãŒãžãäœæããŸãïŒã ãåé¡ïŒlibãã©ã«ããŒå€ã®ã¢ã»ã³ããªããªã©ã®èŠåã¯ç¡èŠã§ããŸãã ãã©ã°ã€ã³ãã€ã³ã¹ããŒã«ããã«ã¯ãVisual Studioã®å®éšçãªã€ã³ã¹ã¿ã³ã¹ã§ãReSharper-ãªãã·ã§ã³-ãšã¯ã¹ãã³ã·ã§ã³ãããŒãžã£ãŒã«ç§»åãã.nupkgãã¡ã€ã«ããããã©ã«ããŒãžã®ãã¹ãæå®ããŸãã
çå®ã®ç¬éïŒReSharper-Extention Managerãéããæ€çŽ¢ããŠãã©ã°ã€ã³ãååã§æ¢ããã€ã³ã¹ããŒã«ããŸãã ãã¹ãŠãæ£ããè¡ãããå Žå-SimpleFixãå©çšå¯èœã«ãªããŸãã
æ¢ç¥ã®ã€ã³ã¹ããŒã«ã®åé¡ïŒ
- ãã©ã°ã€ã³ã¯æ¡åŒµãããŒãžã£ãŒã«ãããŸããã
- ãã©ã°ã€ã³ã¯ã€ã³ã¹ããŒã«ã§ããŸãããQuick-Fixã¯é©åãªå Žæã«è¡šç€ºãããŸããã
ã©ã¡ãã®å Žåãã.nuspecãã¡ã€ã«ã確èªããŠããå ¬åŒã®ãã©ãã«ã·ã¥ãŒãã£ã³ã°ã¬ã€ããèªãããšããå§ããããšããå§ãããŸãã ã¡ãªã¿ã«ããããã ã€ã³ã¹ããŒã©ãŒã¯ããããã®ã¢ãã¬ã¹ïŒ LOCALAPPDATAïŒ \ JetBrains \ Shared \ v02 \ InstallerLogXXXã«ãã°ãèšé²ããŸãããæ¯å圹ã«ç«ããªãããšãããããŸããã ã€ã³ã¹ããŒã«ãæåããå Žåã§ããã¹ããŒãããäŸå€ã«é¢ããå€ãã®æ å ±ããã°ã«æžã蟌ãŸããã€ã³ã¹ããŒã«ãšã©ãŒã®åå ãç解ããããšã¯å®å šã«å°é£ã§ãã
4.ãããã°ã圹ã«ç«ã€ãã³ã
ãããã¬ãŒã䜿çšããŠæ¡åŒµã³ãŒãããŠã©ãŒã¯ã¹ã«ãŒããã«ã¯ãå®éšã€ã³ã¹ã¿ã³ã¹ã®denenv.exeããã»ã¹ãDebug-Attach to Processã§çµåããã ãã§ååã§ãã
ãã¹ãŠã®ãã©ã°ã€ã³ã¯ãExtension ManagerãéããŠã€ã³ã¹ããŒã«ããå¿ èŠããããŸãã ã³ãŒããå€æŽããå Žåããããã®å€æŽãå±éããããã®ä¿èšŒãããæ¹æ³ã¯ãåæ§ã®æŽæ°/åã€ã³ã¹ããŒã«ã§ãã ãã ãããã®ã«ãŒã«ã«ã¯äŸå€ããããŸãïŒæ°ãããã¡ã€ã«/ã¯ã©ã¹ãã³ãŒãã«è¿œå ããããã¹ã¿ãžãªãšã®çµ±åãã€ã³ãã«å€æŽããªãã£ãå ŽåïŒããšãã°ãæ¢åã®ã¯ã€ãã¯ãã£ãã¯ã¹ã®ãšã©ãŒã®ã¿ã€ããå€æŽãããªãã£ãå ŽåïŒããã©ã°ã€ã³ãåã€ã³ã¹ããŒã«ããå¿ èŠã¯ãããŸããã ãã©ã°ã€ã³ã¢ã»ã³ããªãæ°ããããŒãžã§ã³ã«çœ®ãæããã ãã§ååã§ãã RïŒã¯ããã©ã°ã€ã³ãå«ãŸããã¢ã»ã³ããªãè žã®å¥¥æ·±ãã«ä¿åããŸããåã³é£ã³èŸŒãã®ãé²ãã«ã¯ãã³ã³ãã€ã«åŸã«ã¢ã»ã³ããªããå¿ èŠã«å¿ããŠãã³ããŒããMSBuildã¿ãŒã²ããã䜿çšãã䟡å€ããããŸãã ãããè¡ãã«ã¯ã.csprojãã¡ã€ã«ã«æ¬¡ã®ã³ãŒããé 眮ããŸãã
<PropertyGroup> <HostFullIdentifier>ReSharperPlatformVs14YourHive</HostFullIdentifier> </PropertyGroup>
<HostFullIdentifier>ã¿ã°ã¯æåã§å ¥åããã次ã®åœ¢åŒã«ãªããŸãïŒ{Host} {Visual StudioããŒãžã§ã³} {Visual Studioã€ã³ã¹ã¿ã³ã¹å}ã ãªã¹ããªãã·ã§ã³ã¯ãRïŒUltimateãVS 2015ãããã³YourHiveãšãããããã¡ã€ã«ã§æ©èœããŸãã ç¡å¹ãªHostFullIdentifierãæå®ãããšãåºåã§ãããžã§ã¯ãããã«ããããšãã«ãHostFullIdentifierã®ãã¹ãŠã®å¯èœãªããªã¢ã³ãã衚瀺ãããŸãã
5.äŸ2ïŒRïŒAPIã䜿çšããã³ãŒãå€æŽ
ãããããçš®é¡ã®ã¹ã¿ããšã¯äœã§ããïŒ å®éã®ã³ãŒããã³ãŒãã«æ¥ãŠãã ããïŒã-ãã®ã»ã¯ã·ã§ã³ã§ã¯ãRïŒã³ãŒãã®æ§æããªãŒãæ£çŽã«èªã¿åããå€æŽããç°¡åãªãã©ã°ã€ã³ãäœæããŸãã RïŒã®æ©èœãè€è£œããªããã®ããèŠããããã£ãã®ã§ãããå®éã«ã¯éåžžã«ã·ã³ãã«ã§é©çšå¯èœã§ãã ãããŠããããç§ãã¡ãæãã€ãããã®ã§ãã Liståãè¿ãã¡ãœããããããäœããã®çç±ã§returnã¹ããŒãã¡ã³ãã®nullå€ãã¡ãœããã·ã°ããã£ã«å¯Ÿå¿ãã空ã®ã³ã¬ã¯ã·ã§ã³ã«ãã°ãã眮ãæããããšããŸãã äŸïŒ
ããã¯ïŒ
public List<object> FooText() { return null; }
次ã®ããã«ãªããŸããïŒ
public List<object> FooText() { return new List<object>(); }
Null Objectãã¿ãŒã³ã®ç¹æ®ãªã±ãŒã¹ããããŸãã ãã¡ãããnullã³ã¬ã¯ã·ã§ã³ãšemptyã³ã¬ã¯ã·ã§ã³ã¯æå³çã«ç°ãªãããšã«åæãããã®ã¢ãããŒãã®é·æ/çæã«ã€ããŠè©±ãããšãã§ããŸãããããã¯ãã®èšäºã®ç®çã§ã¯ãããŸããã ãã®ãããæè¡çãªå®è£ ã«é²ã¿ãŸãã ãœãŒã¹ã³ãŒããæ£ããããšã«æ°ä»ããããããŸããïŒ 'ã䜿çšããŠçç¥ããŠãã ããïŒ-ã³ã³ãã€ã©ãšRïŒã®èŠ³ç¹ããã¯ãããã§èŠåããããå¿ èŠã¯ãããŸããã ãããã£ãŠãäžèšã®Quick-Fixã¡ã«ããºã ã¯ç§ãã¡ã«ã¯é©ããŠããŸãããã³ã³ããã¹ãã¢ã¯ã·ã§ã³-ã«ã¹ã¿ã ã¢ã¯ã·ã§ã³ãã³ãŒãã®ã»ãšãã©ãã¹ãŠã®éšåã«å²ãåœãŠãããšãã§ãããã¯ããã«æè»ãªããŒã«ã䜿çšããŸãã
[ContextAction(Group = "C#", Name = "Empty Collection Action", Description = "something new")] public class EmptyCollectionContextAction : ContextActionBase { public ICSharpContextActionDataProvider Provider { get; set; } public EmptyCollectionContextAction(ICSharpContextActionDataProvider provider) { Provider = provider; } public override string Text { get; } = "Return empty collection"; }
ã³ã³ããã¹ãã¢ã¯ã·ã§ã³ã®å¯èŠæ§ã¯ãIsAvailableã¡ãœããããªãŒããŒã©ã€ãããããšã«ãããQuick-Fixãšåæ§ã«å¶åŸ¡ãããŸãã
public override bool IsAvailable(IUserDataHolder cache) { var method = Provider.GetSelectedElement<IMethodDeclaration>(); bool insideOfMethod = method != null; if (insideOfMethod) { bool returnsNull = ReturnsNullOrEmpty(); bool isGenericList = HasCorrectReturnType(method); return returnsNull && isGenericList; } return false; }
ã¡ãœããå ã«ãããšå€æããã®ã¯éåžžã«ç°¡åã§ãïŒã³ãŒããåç §ïŒã 次ã«ã以äžã決å®ããå¿ èŠããããŸãã
- é©åãªreturnã¹ããŒãã¡ã³ãã䜿çšããŠããŸããïŒ
- ã¡ãœãããé©åãªåãè¿ããã©ããã
è¿åã®ç¢ºèªïŒ
ReturnsNullOrEmptyïŒïŒ
private bool ReturnsNullOrEmpty() { var returnStatement = Provider.GetSelectedElement<IReturnStatement>(false); if (returnStatement != null) { ICSharpExpression value = returnStatement.Value; return value == null || value.ConstantValue.IsPureNull(CSharpLanguage.Instance); } return false; }
ã¡ãœããã®æ»ãå€ã®åã¯ããè€éã§ãã è¿ãããåãäžè¬çãªãªã¹ãã§ããããããããç¶æ¿ãããŠãããã確èªããŸãããïŒååã¯ä»ã®ã³ã¬ã¯ã·ã§ã³ã§ãåãã§ãïŒïŒ
HasCorrectReturnTypeïŒïŒ-ãªãã·ã§ã³çªå·1
private static bool HasCorrectReturnType(IMethodDeclaration method) { IDeclaredType declaredType = method.DeclaredElement.ReturnType as IDeclaredType; if (declaredType == null || declaredType.IsVoid()) return false; ISubstitution sub = declaredType.GetSubstitution(); if (sub.IsEmpty()) return false; IType parameterType = sub.Apply(sub.Domain[0]); IMethod declaredElement = method.DeclaredElement; IType realType = declaredElement.Type(); var predefinedType = declaredElement.Module.GetPredefinedType(); ITypeElement generic = predefinedType.GenericList.GetTypeElement(); IType sampleType = EmptySubstitution.INSTANCE .Extend(generic.TypeParameters, new IType[] { parameterType }) .Apply(predefinedType.GenericList); bool isGenericList = realType.IsImplicitlyConvertibleTo(sampleType, new CSharpTypeConversionRule(declaredElement.Module)); return isGenericList; }
ããåçŽãªãªãã·ã§ã³ããããŸãããããã»ã©æè»ã§ã¯ãããŸãã-CLRåã§åãæ¯èŒããŸãã
HasCorrectReturnTypeïŒïŒ-ãªãã·ã§ã³çªå·2
private static bool HasCorrectReturnType(IMethodDeclaration method) { IDeclaredType declaredType = method.DeclaredElement.ReturnType as IDeclaredType; if (declaredType == null || declaredType.IsVoid()) return false; ITypeElement element = declaredType.GetTypeElement(); string fullName = element.GetClrName().FullName; bool isGenericList = fullName == "System.Collections.Generic.List`1"; return isGenericList; }
æåŸã«ãæè¯ã®éšåã¯nullãæ°ãããªã¹ã<Foo>ïŒïŒã«çœ®ãæããããšã§ãïŒ
ReplaceTypeïŒïŒ
protected override Action<ITextControl> ExecutePsiTransaction(ISolution solution, IProgressIndicator progress) { ReplaceType(); return null; } private void ReplaceType() { IMethodDeclaration method = Provider.GetSelectedElement<IMethodDeclaration>(); IType type = method.DeclaredElement.ReturnType; string typePresentableName = type.GetPresentableName(CSharpLanguage.Instance); CSharpElementFactory factory = CSharpElementFactory.GetInstance(Provider.PsiModule); string code = $"new {typePresentableName}()"; ICSharpExpression newExpression = factory.CreateExpression(code); IReturnStatement returnStatement = Provider.GetSelectedElement<IReturnStatement>(false); returnStatement.SetValue(newExpression); }
RïŒAPIã§ã³ãŒããèšè¿°ãããå解ãããããã®ã¯ç°¡åã§ã¯ãããŸããã1ã€ã®å Žæã«ãã¹ãŠã®çã¿ã泚ã蟌ãããã«ãäžèšã®ãªã¹ãã«æ æã«ã³ã¡ã³ãããŸããã§ããã ããã¥ã¡ã³ãã«ã¯ã®ã£ããããããå©çšå¯èœãªäŸã¯ã»ãšãã©ãããŸãããã³ãŒãã«é¢ããXMLã³ã¡ã³ãããããŸããã éçºãããåã¡ãœããã«èŠãã¿ããããã¬ãŒãç©æ¥µçã«äœ¿çšããå¿ èŠããããŸãã ç§ã¯åŒ·èª¿ããŸã-RïŒAPIãæäœãããšãã®ãããã¬ãŒã¯ãæ§æããªãŒã移åããããã®æãéèŠãªããŒã«ã«ãªãã€ã€ãããŸãã GitHubã§ã®ããŒã¯ã©ã¹ã®æ€çŽ¢ã¯ãæ·±å»ãªå©ãã«ããªããŸããäžå®æ°ã®ã³ãŒããµã³ãã«ãèŠã€ããããšãã§ããŸãã
6. RïŒAPIã䜿çšãããã©ã°ã€ã³ã®æ©èœãã¹ã
RïŒAPIã®åªããæ©èœã®1ã€ã¯ãRïŒã€ã³ã¹ã¿ã³ã¹ãã¡ã¢ãªã«æé»çã«ãããã€ãããã¹ãæžã¿ã®Quick-FixãŸãã¯ã³ã³ããã¹ãã¢ã¯ã·ã§ã³ãããã¹ãã«é©çšããããšã§ããã¹ãããã£ãŒãããå€æãããããã¹ããäºæ³ãããããã¹ããšæ¯èŒããæ©èœã§ãã ãããŠãããã¯ãã¹ãŠãæãåçŽãªåäœãã¹ããæžãããšã«å¹æµãããå°éã®ã³ãŒããæžãããšã§å®çŸããŸãã ãšããã§ãRïŒã¯NUnitã䜿çšããŸãã è¡ããïŒ
ãã©ã°ã€ã³ã䜿çšããŠããã¹ããå«ãå¥ã®ãããžã§ã¯ãããœãªã¥ãŒã·ã§ã³ã«è¿œå ããŸãã JetBrains.ReSharper.SDK.Testsããã±ãŒãžãã€ã³ã¹ããŒã«ããŸãã æå°éã®äœæ¥äŸãäœæããã«ã¯ããããžã§ã¯ãã«æ¬¡ã®ãã¡ã€ã«æ§é ãäœæããå¿ èŠããããŸãã
ãã®æ§é ã¯æšæºçã§ã¯ãããŸãããããããã€ãç°¡åã§ãåŸæ¥ã®CïŒãœãªã¥ãŒã·ã§ã³æ§é ã«è¿ããªã£ãŠããŸãã nuget.configããã³TestEnvironment.csãã¡ã€ã«ãå¿ èŠã§ãã
nuget.config
<?xml version="1.0" encoding="utf-8" ?> <configuration> <config> </config> <packageSources> <clear /> <add key="jb-gallery" value="http://jb-gallery.azurewebsites.net/api/v2/curated-feeds/TestNuggets/" /> <add key="nuget.org" value="http://www.nuget.org/api/v2/" /> </packageSources> <disabledPackageSources> <clear /> </disabledPackageSources> <packageRestore> <add key="enabled" value="True" /> <add key="automatic" value="False" /> </packageRestore> </configuration>
TestEnvironment.cs
[assembly: RequiresSTA] [ZoneDefinition] public class TestEnvironmentZone : ITestsZone, IRequire<PsiFeatureTestZone>{ } [SetUpFixture] public class ReSharperTestEnvironmentAssembly : ExtensionTestEnvironmentAssembly<TestEnvironmentZone> { }
æºåãå®äºãããããã¹ãã®äœæã«çŽæ¥é²ã¿ãŸãã ã³ã³ããã¹ãã¢ã¯ã·ã§ã³ãã¹ããå«ãã¯ã©ã¹ã¯ãCSharpContextActionExecuteTestBaseããç¶æ¿ããå¿ èŠããããŸãã
[TestFixture] public class EmptyCollectionContextActionTests : CSharpContextActionExecuteTestBase<EmptyCollectionContextAction> { protected override string ExtraPath => "EmptyCollectionContextActionTests"; protected override string RelativeTestDataPath => "EmptyCollectionContextActionTests"; [Test] public void Test01() { DoTestFiles("Test01.cs"); } }
ã¹ã¯ãªãŒã³ã·ã§ããã§æ¢ã«èŠãTest01.csãã¡ã€ã«ã¯ãã³ã³ããã¹ãã¢ã¯ã·ã§ã³ãé©çšãããã³ãŒããå«ããœãŒã¹ãã¡ã€ã«ã§ãã Test01.cs.goldã¯äžçš®ã®ãæåŸ ãããåºåãã§ãããã³ã³ããã¹ãã¢ã¯ã·ã§ã³ã®é©çšåŸã«äºæ³ãããã³ãŒãã§ãã ã³ã³ããã¹ãã¢ã¯ã·ã§ã³ãTest01.csã«é©çšãããšããã¹ãã¯åæ ŒãšèŠãªãããTest01.cs.goldãååŸãããŸãã
ç¬èªã®ãã¹ããäœæããå ŽåãExtraPathããããã£ãšRelativeTestDataPathããããã£ã®å€ã決å®ãããœãŒã¹ãšãŽãŒã«ããã¡ã€ã«ãå«ããã©ã«ããŒã®ååãšåãå€ã«èšå®ããå¿ èŠããããŸãã ãããã®ãã¡ã€ã«ãã³ã³ãã€ã«ããå¿ èŠã¯ãããŸããããããã£ãŠãæ¶ç©ºã®ãšã©ãŒã¡ãã»ãŒãžãåãé€ãããã«ãBuildActionïŒNoneãå®å šã«èšå®ããç¡èŠããRïŒãè¿œå ããå¿ èŠããããŸãã ãœãŒã¹ãã¡ã€ã«ãšãŽãŒã«ããã¡ã€ã«ã®ã³ã³ãã³ãã«é¢ããŠã¯ãã³ã³ããã¹ãã¢ã¯ã·ã§ã³ã®å Žåãã³ã³ããã¹ãã¢ã¯ã·ã§ã³ãåŒã³åºããããšãã®ãã£ã¬ããã®äœçœ®ã瀺ãå¿ èŠããããŸããããã¯{caret}åœä»€ã䜿çšããŠè¡ãããŸãã
using System; using System.Collections.Generic; namespace N { public class C { public List<int> FooMethod() { return {caret}null; } } }
察å¿ãããŽãŒã«ããã¡ã€ã«ïŒ
using System; using System.Collections.Generic; namespace N { public class C { public List<int> FooMethod() { return { caret}new List<int>(); } } }
ãã¹ãäžã«ïŒãœãŒã¹ãã¡ã€ã«+ã³ã³ããã¹ãã¢ã¯ã·ã§ã³ïŒïŒ=ãŽãŒã«ããã¡ã€ã«ã®å Žåããã¹ãã¯å€±æããã³ã³ããã¹ãã¢ã¯ã·ã§ã³ãé©çšããå®éã®çµæãå«ãåããã©ã«ããŒã«tmpãã¡ã€ã«ãäœæãããŸãã
ãã¹ããå®è¡ããããã«å®è¡ããŸãã...åé¡ã®ãªã¹ããšãããã解決ããæ¹æ³ã«ããã«è¡ããŸãã
- äŸå€ããã¡ã€ã«ãååšããŸãããã¯æãåçŽãªäŸå€ã§ãããã©ã«ãæ§é ãšãExtraPathãRelativeTestDataPathããããã£ã®å¯Ÿå¿ããå€ã確èªããŸãã
- SetUpFixtureã®äŸå€ã§ãã¹ããã¯ã©ãã·ã¥ããŸã-nuget.configãã¡ã€ã«ãšTestEnvironment.csãã¡ã€ã«ã®å Žæãšå 容ã確èªããŸãã
- äŸå€ããã¹ãåºåã¯ãŽãŒã«ããã¡ã€ã«ãšç°ãªããŸãã-äœæãããtmpãã¡ã€ã«ã調ã¹ããããã¬ã§ãã¹ããå®è¡ããŸãã
- ã³ãŒãã®ä»£ããã«ãtmp-fileã«ã¯ãNOT AVAILABLEããšãã1è¡ãå«ãŸããŠããŸããããããããœãŒã¹ãã¡ã€ã«å ã«ãã£ã¬ããã·ã³ãã«ããªãããæäœäžã«ã³ã³ããã¹ãã¢ã¯ã·ã§ã³ãäŸå€ãã¹ããŒããŸããã
- æãèå³æ·±ãã±ãŒã¹ã¯ããœãŒã¹ãã¡ã€ã«ãšãŽãŒã«ããã¡ã€ã«ã®å 容ã«é¢ä¿ãªãããã¹ããåžžã«æåããããšã§ãã å ã®ãã¡ã€ã«ãåé€ãããšãã¯ã©ãã·ã¥ããŸãã ContextActionTestBaseããContext Actionã®ãã¹ããç¶æ¿ããExtraPathããããã£ãèšå®ããªãã£ããšãã«ããã®äžå¿«ãªåäœãçºçããŸããã
以äžã§ãã å®å šãªå®äŸãGitHubã«ãããŸã ã æåã®ãã©ã°ã€ã³ãéçºããæéããç§ã«ããã£ãæéããã¯ããã«çããªãããšãé¡ã£ãŠããŸã=ïŒ
UPDïŒäŸ¿å©ãªãªã³ã¯ïŒ
ReSharper DevGuide
JetBrainséçºè ã³ãã¥ããã£-> ReSharper Open API / SDK
Googleã°ã«ãŒãïŒresharper-plugins