{"id":16454,"date":"2018-05-03T13:22:58","date_gmt":"2018-05-03T13:22:58","guid":{"rendered":"https:\/\/blog.jetbrains.com\/dotnet\/?p=17643"},"modified":"2020-05-28T09:38:17","modified_gmt":"2020-05-28T09:38:17","slug":"what-are-jetbrains-annotations","status":"publish","type":"dotnet","link":"https:\/\/blog.jetbrains.com\/en\/dotnet\/2018\/05\/03\/what-are-jetbrains-annotations","title":{"rendered":"What are JetBrains Annotations &#8211; and how to get them?"},"content":{"rendered":"<p>In our previous blog post, we looked at <a href=\"https:\/\/blog.jetbrains.com\/dotnet\/2018\/05\/02\/improving-rider-resharper-code-analysis-using-jetbrains-annotations\/\">an example of using JetBrains Annotations<\/a>. We saw they are an easy way to improve Rider (and ReSharper&#8217;s) code analysis, code completion and navigation by adding some simple hints in our code, in the form of attributes.\u00a0In this post, we&#8217;ll look a bit more at the background: what are these annotations? And how do we add them to our source code?<\/p>\n<p>In this series:<\/p>\n<ul>\n<li><a href=\"https:\/\/blog.jetbrains.com\/dotnet\/2018\/05\/02\/improving-rider-resharper-code-analysis-using-jetbrains-annotations\/\">Improving Rider and ReSharper code analysis using JetBrains Annotations<\/a><\/li>\n<li><a href=\"https:\/\/blog.jetbrains.com\/dotnet\/2018\/05\/03\/what-are-jetbrains-annotations\/\">What are JetBrains Annotations &#8211; and how to get them?<\/a><\/li>\n<li><a href=\"https:\/\/blog.jetbrains.com\/dotnet\/2018\/05\/04\/better-null-checks-string-formatting-path-completion-jetbrains-annotations\/\">Better null checks, string formatting and path completion with JetBrains Annotations<\/a><\/li>\n<\/ul>\n<p>Before we look at how to add\u00a0JetBrains Annotations to our code, let&#8217;s take one step back and look at what they are.<\/p>\n<h2>What are JetBrains Annotations?<\/h2>\n<p>Rider and ReSharper&#8217;s code analysis and inspections are very smart on their own and help find code smells, dead code, potential compile time or run time errors, and more.<\/p>\n<p>We have already seen that we can make this mechanism smarter by telling Rider and ReSharper what we mean. In our previous post, we saw that the ReSharper engine\u00a0knew we were working with strings, but only <em>we<\/em>\u00a0as the author of that code knew these strings were controllers and actions. Code analysis may warn us that a value can be null, but maybe the underlying code never returns null at all. Only one way to tell the engine: <strong>annotations<\/strong>.<!--more--><\/p>\n<p>Annotations can exist as attributes in our code, as we have seen, or as XML files. Rider and ReSharper ship with a copy of the <a href=\"https:\/\/github.com\/JetBrains\/ExternalAnnotations\" target=\"_blank\" rel=\"noopener\">XML annotations we have open-sourced on GitHub<\/a>.\u00a0All of\u00a0the .NET base classes have been annotated, as well as popular frameworks such as Caliburn.Micro,\u00a0NUnit, Nancy&#8217;s Razor view engine, xUnit, log4net and so on.<\/p>\n<p>For example, an annotation tells Rider and ReSharper that <a href=\"https:\/\/github.com\/JetBrains\/ExternalAnnotations\/blob\/master\/Annotations\/.NETCore\/System.Console\/Attributes.xml#L53\" target=\"_blank\" rel=\"noopener\"><code>System.Console.WriteLine<\/code> has a first argument that is a &#8220;string format&#8221; method<\/a>. The IDE will use that information to provide additional code completion, will check for string format placeholders, etc.<\/p>\n<h2>How to add JetBrains Annotations to our own codebase?<\/h2>\n<p>Good for me: my colleague Matt already wrote about\u00a0<a href=\"https:\/\/blog.jetbrains.com\/dotnet\/2015\/08\/12\/how-to-use-jetbrains-annotations-to-improve-resharper-inspections\/\">adding JetBrains Annotations in ReSharper<\/a> a while ago, so let&#8217;s focus on Rider here. We can reference the JetBrains Annotations in two ways: by adding the official\u00a0<a href=\"https:\/\/www.nuget.org\/packages\/JetBrains.Annotations\/\" target=\"_blank\" rel=\"noopener\">JetBrains.Annotations\u00a0NuGet package<\/a>\u00a0to our project, or by adding the annotations to the source code of our project. Now which option to pick&#8230;<\/p>\n<p>As a rule of thumb, it&#8217;s usually best to reference\u00a0the\u00a0<a href=\"https:\/\/www.nuget.org\/packages\/JetBrains.Annotations\/\" target=\"_blank\" rel=\"noopener\">JetBrains.Annotations\u00a0NuGet package<\/a>\u00a0when a project is not intended to be shared outside a development team. The NuGet package uses the\u00a0<a href=\"https:\/\/msdn.microsoft.com\/en-us\/library\/system.diagnostics.conditionalattribute.aspx\" target=\"_blank\" rel=\"noopener\"><code>[Conditional(\"JETBRAINS_ANNOTATIONS\")]<\/code> attribute<\/a>\u00a0to ensure the annotations\u00a0are not\u00a0compiled into the resulting assembly. In other words: it is there while developing and your team can use the\u00a0annotations, but\u00a0it&#8217;s gone when compiled.<\/p>\n<p>When building a library that is intended to be shipped to others, we can include the JetBrains Annotations source code directly in our project (or compile with the <code>JETBRAINS_ANNOTATIONS<\/code> flag set).\u00a0As long as the <code>JetBrains.Annotations<\/code> namespace exists, Rider and ReSharper will make use of them. For us, when we are developing our library, and for consumers of our library if they are using Rider or ReSharper.<\/p>\n<p>Adding the NuGet package can be done using the NuGet client, adding the annotations as source code can be done by copying it from the settings under\u00a0<strong>Editor | Inspection Settings | Code Annotations<\/strong>:<\/p>\n<p><img decoding=\"async\" loading=\"lazy\" class=\"alignnone size-full wp-image-17626\" src=\"https:\/\/blog.jetbrains.com\/wp-content\/uploads\/2018\/02\/dotnet-code-annotations-source-code.png\" alt=\"Adding JetBrains Annotations source code in Rider\" width=\"800\" height=\"500\" \/><\/p>\n<p>Now that we have the annotations referenced, we can look at a few of them! We&#8217;ll do that in the last post of our series. Stay tuned!<\/p>\n<p><strong><a href=\"https:\/\/www.jetbrains.com\/rider\" target=\"_blank\" rel=\"noopener\">Download Rider 2018.1<\/a>\u00a0or <a href=\"https:\/\/www.jetbrains.com\/resharper\" target=\"_blank\" rel=\"noopener\">give ReSharper a try<\/a>!<\/strong> We&#8217;d love to hear your feedback!<\/p>\n","protected":false},"author":118,"featured_media":0,"comment_status":"open","ping_status":"open","template":"","categories":[1401],"tags":[1969,211,4702,46,1978],"cross-post-tag":[],"acf":[],"_links":{"self":[{"href":"https:\/\/blog.jetbrains.com\/en\/wp-json\/wp\/v2\/dotnet\/16454"}],"collection":[{"href":"https:\/\/blog.jetbrains.com\/en\/wp-json\/wp\/v2\/dotnet"}],"about":[{"href":"https:\/\/blog.jetbrains.com\/en\/wp-json\/wp\/v2\/types\/dotnet"}],"author":[{"embeddable":true,"href":"https:\/\/blog.jetbrains.com\/en\/wp-json\/wp\/v2\/users\/118"}],"replies":[{"embeddable":true,"href":"https:\/\/blog.jetbrains.com\/en\/wp-json\/wp\/v2\/comments?post=16454"}],"version-history":[{"count":0,"href":"https:\/\/blog.jetbrains.com\/en\/wp-json\/wp\/v2\/dotnet\/16454\/revisions"}],"wp:attachment":[{"href":"https:\/\/blog.jetbrains.com\/en\/wp-json\/wp\/v2\/media?parent=16454"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blog.jetbrains.com\/en\/wp-json\/wp\/v2\/categories?post=16454"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blog.jetbrains.com\/en\/wp-json\/wp\/v2\/tags?post=16454"},{"taxonomy":"cross-post-tag","embeddable":true,"href":"https:\/\/blog.jetbrains.com\/en\/wp-json\/wp\/v2\/cross-post-tag?post=16454"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}