From 064b4786f14b161c867c779121a60b4d03d338af Mon Sep 17 00:00:00 2001 From: Artem Pianykh Date: Thu, 30 Apr 2020 06:16:42 -0700 Subject: [PATCH] [nullsafe] Mark @Nullsafe with @TypeQualifierDefault&Co for Kotlin interop Summary: Kotlin has an experimental support for [JSR-305 custom nullability qualifiers](https://github.com/Kotlin/KEEP/blob/master/proposals/jsr-305-custom-nullability-qualifiers.md). Annotating Nullsafe in a special way makes kotlinc recognize it as such custom nullability qualifier and therefore treat types coming from Nullsafe Java classes **not** as platform types, but rather proper nonnull/nullable, which affects: 1. Generated bytecode (more thorough null-checks). 2. Type inference in the IDE. NOTE re: p.1: one might expect that with properly annotated Java code Kotlin would avoid inserting runtime checks. This is not how Kotlin-Java interop works - in reality Kotlin does even more runtime checking for Java code annotated as Nonull, which IMO is a good thing, since you can't trust Java anyway. Reviewed By: mityal Differential Revision: D21278440 fbshipit-source-id: d0598738a --- .../kotlin-annotations-jvm-1.3.72.jar | Bin 0 -> 2676 bytes infer/annotations/Makefile | 3 ++- infer/annotations/pom.xml | 6 ++++++ .../com/facebook/infer/annotation/Nullsafe.java | 13 +++++++++++++ 4 files changed, 21 insertions(+), 1 deletion(-) create mode 100644 dependencies/java/kotlin-annotations/kotlin-annotations-jvm-1.3.72.jar diff --git a/dependencies/java/kotlin-annotations/kotlin-annotations-jvm-1.3.72.jar b/dependencies/java/kotlin-annotations/kotlin-annotations-jvm-1.3.72.jar new file mode 100644 index 0000000000000000000000000000000000000000..54bd507821c4455520d21c3d6dda3b7e507b02e8 GIT binary patch literal 2676 zcmaJ@c|4SP7@wvYlKUts_mTTv?a+Zj%oyX$Qi~BXni*o;ti|NW%@AsKlSHZLH6q!|A+(6?*bZj04ecxBhuW?#>&#kSqEvggzWCJMQH2v z3nH{Ndb)e79QB3_C#RoJgSp56{O417f%;@10gJ)^@64~;#J{wm@%TUjnt%z!hkO?z z`E5u*818?t4!X^C$xR^87?7G9!(8w_zQIV$iQo^X>m0|TLqbmHcp|{&64YL!&@Q(B zs)VRzwzIJI>(RjjQd{ae>v;MPrHAEIp4t<30@~y*9Q*45XTq`qf4Zz6t-E{Sx0dnM zm6&MWpv1c5;^bIiUScqf)MfbKPpa>l$|m>BGN*$2|Y2CBjWR z21O?@EyTCY2SVNo{)`&36%{HSH`zZOP5!H7%4^yNhSQarP}|EEr5&a})*&gA{5oHH zKU?8ts90su949Rk_3)v^#23pdmGFmj;=ZGC6F=@5m?V<$OB$}zUKhAz%qF9oWdllT-^`zy>^}`oyh~;`Um5EPJ z$3XO%_V2*!r>D{5+HE;N+esjmH`W&!N+6Z>=#!!yv8|?eQ{DB>Q}0#=D5wTpR_n~@xPDv1P%~++Prq@yA1!Ty zIMFo_qmYr`8!q5VwbjxVeJSeb#!nu6$uyl&8`OA8Nx-+~5vLj`URni)nACdp9$xpl z<+gLKHuj-X>2eokLm9#e*;ribal8BSe*Q@gXOmIlvcfB|QhLW4e2!=?l|AkJ{gx!V zw_nPAET^BKIKw&QyEa+0ID{32Dxm;bHn8sU0 z;&VGz!&9ToG7@Hk;z*~4Ef)J)kxX(&x1n57R&Q-Ms1~*qM4xJHDL2CvPIr-_;CW{I z6^t`7p51vBtPSnS8~>^LLZy3o>XqigZg_=3l^7*c`o&3%Un2{-@>J`Qq>mPI0dn(9 z5m8H=uJ7oEATP}fo6g98kl0Q_AQ>!4g(}@WpW{1!1tu2|JeRTOR%_qd7()4e17?_ULgA2GTk49bRr9j11U zIn_WQa8~%F2j6ty4X?AfbEUFl`+HpZjOZ_#@1oSiXZ>NugaJbEYv}qJJ}y?P^)s+5 zuR%Z{t&JuAydIo@9Tgh#QR#fA1(dkCNbHzLG~<++`j&(heo^;p&h|r(lltU~cUL2$ zemcY=kgDV1GNc2Qp44cPGCM&P+wzqup zUK2mUxRG9xi|;>t>AUVkqI|Eb=#{Xdz?kWUxrk;FUDI2`vwH=KI`@u*6T8P8>lzvS zu3<}z7CZK7|44KH{(xIYz4|=zXI&E9>zDsw>Lf0bn%+bVGFLaXVDG8M_D>1+Z(9@6 zC0FX(x{fkS$l=&0oxh_~96Yfk4c&09B>LP`Xsa-;>|yGUXIJG4YZ$UYNsDK)8%F2o zA%P>iFJDrethk3(^W!18H>&znWXrIL1S)RSu7ycd6nbKW38##%r4?zYZ&ha@XZxVM zXR8Dct_4C}itkt;2GnKsEe!*d9Iz$|D;=P)!%Pz@dRt&Fq$N1oBhOSEJ~t${qvFit z);o0`hP(ItosGu8g2k62e4g*#e$X(Jl*;EjV6C4{9_bc2X>!wfr@@o>sDL%xv)4AS z+Pso$Wa`JXkG;OpQ?jBn%b8qWTD4rbY&(raY`(^*a@mBkV{E- zb0?Sj$2aV>lA|jrmZki1A!Q1l01K{m%bPih zDBY>HUE_?A1qS>Uj%Py_OXHeD#~oeJ`t5f!AO-Dg#|PzNMsUvyjLXY2d}0r+dE!f; z_pL<=E9Ip!;x4O=mLY1(mi4_E)VEUAnfEh)kvuP?hD;wgU)rXVS7;rvVqg&8%ZAt^ zHi0EJZ|v#7tO6kdVwiKjpBp+R|npoVPE+@Hv^~pzsm&2);|X4;4q;4 zWb)qwaZLVWa6n|B`~>>i^1nyGvHXw0A?O3jZxC=U0Nf^OA J;J}AD_!k`)1Ofm6 literal 0 HcmV?d00001 diff --git a/infer/annotations/Makefile b/infer/annotations/Makefile index d4a292142..149204880 100644 --- a/infer/annotations/Makefile +++ b/infer/annotations/Makefile @@ -8,6 +8,7 @@ include $(ROOT_DIR)/Makefile.config CWD = $(shell pwd) JSR_JAR = $(DEPENDENCIES_DIR)/java/jsr-305/jsr305.jar +KOTLIN_ANNOT_JAR = $(DEPENDENCIES_DIR)/java/kotlin-annotations/kotlin-annotations-jvm-1.3.72.jar SOURCES_DIR = src/main/java ANNOT_SOURCES = $(shell find $(SOURCES_DIR)/com/facebook/infer/annotation -name "*.java") ANNOT_CLASSES = 'annot_classes' @@ -19,7 +20,7 @@ all: $(ANNOTATIONS_JAR) $(SOURCES_JAR) $(ANNOTATIONS_JAR): $(ANNOT_SOURCES) $(MKDIR_P) $(ANNOT_CLASSES) - $(JAVAC) -source 7 -target 7 -cp $(JSR_JAR) $(ANNOT_SOURCES) -d $(ANNOT_CLASSES) + $(JAVAC) -source 7 -target 7 -cp $(JSR_JAR):$(KOTLIN_ANNOT_JAR) $(ANNOT_SOURCES) -d $(ANNOT_CLASSES) cd $(ANNOT_CLASSES) && jar cvf $(ANNOTATIONS_JAR) com $(SOURCES_JAR): $(ANNOT_SOURCES) diff --git a/infer/annotations/pom.xml b/infer/annotations/pom.xml index 8db5f97c8..732fcc88c 100644 --- a/infer/annotations/pom.xml +++ b/infer/annotations/pom.xml @@ -65,6 +65,12 @@ jsr305 3.0.1 + + + org.jetbrains.kotlin + kotlin-annotations-jvm + 1.3.72 + diff --git a/infer/annotations/src/main/java/com/facebook/infer/annotation/Nullsafe.java b/infer/annotations/src/main/java/com/facebook/infer/annotation/Nullsafe.java index 8602a932c..dce0dacc1 100644 --- a/infer/annotations/src/main/java/com/facebook/infer/annotation/Nullsafe.java +++ b/infer/annotations/src/main/java/com/facebook/infer/annotation/Nullsafe.java @@ -11,9 +11,22 @@ import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; +import javax.annotation.Nonnull; +import javax.annotation.meta.TypeQualifierDefault; +import kotlin.annotations.jvm.MigrationStatus; +import kotlin.annotations.jvm.UnderMigration; @Retention(RetentionPolicy.CLASS) @Target({ElementType.TYPE}) +// These 2 annotations are needed for better interop of @Nullsafe with Kotlin, +// essentially telling it that both params and return values are non-null by +// default. +@Nonnull +@TypeQualifierDefault({ElementType.METHOD, ElementType.PARAMETER}) +// This annotation is needed for kotlinc to recognize {@code +// TypeQualifierDefault} without explicitly passing -Xjsr305=strict flag (which +// may be problematic in large codebases). +@UnderMigration(status = MigrationStatus.STRICT) /** * Configures nullability checking mode of annotated classes; a more general version of {@link * NullsafeStrict}.