0
0
mirror of https://github.com/ankidroid/Anki-Android.git synced 2024-09-19 19:42:17 +02:00

Allow JetBrains @Contract annotations

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
This commit is contained in:
David Allison 2020-05-15 01:14:06 +01:00 committed by Mike Hardy
parent 7028a63f01
commit 1cdd07d6d7
4 changed files with 77 additions and 0 deletions

View File

@ -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"

View File

@ -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);

49
annotations/README.md Normal file
View File

@ -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.

View File

@ -0,0 +1,24 @@
<!--
Copyright (c) 2020 David Allison <davidallisongithub@gmail.com>
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>