Skip to content

Commit

Permalink
Allow JetBrains @contract annotations
Browse files Browse the repository at this point in the history
Contract annotations allow us to write contracts for methods such as:
"null -> true" (TextUtils.isEmpty()), this allows further lint warnings
on Android framework methods, which should be annotated, but aren't yet.

These should be written inline when possible, but we also include a
folder of annotations for our external libraries

Further instructions for external annotations are detailed in README.md
  • Loading branch information
david-allison authored and mikehardy committed May 15, 2020
1 parent 7028a63 commit 1cdd07d
Show file tree
Hide file tree
Showing 4 changed files with 77 additions and 0 deletions.
1 change: 1 addition & 0 deletions AnkiDroid/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,7 @@ tasks.withType(JavaCompile) {
apply from: "./jacoco.gradle"

dependencies {
compileOnly 'org.jetbrains:annotations:16.0.1'
compileOnly "com.google.auto.service:auto-service-annotations:1.0-rc6"
annotationProcessor "com.google.auto.service:auto-service:1.0-rc6"

Expand Down
3 changes: 3 additions & 0 deletions AnkiDroid/src/main/java/com/ichi2/utils/Assert.java
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,10 @@

package com.ichi2.utils;

import org.jetbrains.annotations.Contract;

public class Assert {
@Contract("false, _, _ -> fail")
public static void that(boolean condition, String message, Object... args) {
if (!condition) {
String msg = String.format(message, args);
Expand Down
49 changes: 49 additions & 0 deletions annotations/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
# External Annotations for Android Standard Library

## Rationale

`@Contract` annotations for Android methods allow the removal of tautotlogical lint checks.

For example: if `TextUtils.isEmpty(str)` returns `false`, then `str` is non-null. `@Contract` allows us to specify this invariant to the linter, which reduces lint warnings and/or unnecessary code.

**@Contract annotations should be inline whenever possible**. This folder exists so we can define our own contract annotations on our dependencies.

## Syntax

See: https://www.jetbrains.com/help/idea/contract-annotations.html

## Installation Instructions

* Open an Android Source file in Android Studio
* Move the Cursor over a method and bring up the Quick Fixes Menu (Alt + Enter)
* Select "Add Method Contract to `[method]`"
* Enter a dummy annotation: `null -> null`
* Select the folder containing this file as the annotations root

Annotations should now appear

## Modificiation Instructions

* In Android Studio Settings: `jdk.table.xml`
* You can find the element under one of the `<jdk>` elements as a `file://` URL:
* Removing this line will allow the selection of another annotations root.

Sample:
```xml
<jdk version="2">
<name value="Android API 28 Platform" />
<type value="Android SDK" />
<version value="java version &quot;1.8.0_112-release&quot;" />
<homePath value="C:\Users\David\AppData\Local\Android\Sdk" />
<roots>
<annotationsPath>
<root type="composite">
<root url="jar://$USER_HOME$/AppData/Local/Android/Sdk/platforms/android-28/data/annotations.zip!/" type="simple" />
<root url="file://C:/GitHub/Anki-Android-David/annotations" type="simple" />
```

## Future Goals

It would be ideal if these could be set on a per-project basis. I haven't had the time to determine whether this is possible.

These annotations are not yet supported by our automated tooling.
24 changes: 24 additions & 0 deletions annotations/android/text/annotations.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
<!--
Copyright (c) 2020 David Allison <[email protected]>
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
Foundation; either version 3 of the License, or (at your option) any later
version.
This program is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with
this program. If not, see <http://www.gnu.org/licenses/>.
-->

<root>
<item name='android.text.TextUtils boolean isEmpty(java.lang.CharSequence)'>
<annotation name='org.jetbrains.annotations.Contract'>
<val name="value" val="&quot;null -&gt; true&quot;" />
<val name="pure" val="true" />
</annotation>
</item>
</root>

0 comments on commit 1cdd07d

Please sign in to comment.