Giter Site home page Giter Site logo

java-annotations's Introduction

Annotations for JVM-based languages

official JetBrains project License Maven Central javadoc

A set of Java annotations which can be used in JVM-based languages. They serve as an additional documentation and can be interpreted by IDEs and static analysis tools to improve code analysis.

Change Log | Contributing | Code of Conduct

Documentation

Using the annotations

The annotations are published on Maven Central. To add a dependency using gradle write the following in the build.gradle file (Groovy DSL)

dependencies {
    compileOnly 'org.jetbrains:annotations:25.0.0'
}

or in the build.gradle.kts file (Kotlin DSL)

dependencies {
    compileOnly("org.jetbrains:annotations:25.0.0")
}

To add a dependency using Maven, write the following in pom.xml:

<dependency>
  <groupId>org.jetbrains</groupId>
  <artifactId>annotations</artifactId>
  <version>25.0.0</version>
  <scope>provided</scope>
</dependency>

annotations artifact requires JDK 1.8 or higher. If your project is compiled using JDK 1.5, 1.6 or 1.7 you can use the annotations-java5 artifact instead. Please note that annotations-java5 artifact is considered a legacy and will receive no further updates. The latest version of annotations-java5 is 24.1.0.

java-annotations's People

Contributors

akozlova avatar amaembo avatar anton-vasilev avatar basleijdekkers avatar cdracm avatar chashnikov avatar dmitry-avdeev avatar dmpanov avatar donnerpeter avatar dovchinnikov avatar gorrus avatar jacksonbailey avatar janothan avatar jarviscraft avatar jreznot avatar jt122406 avatar kashike avatar maxmedvedev avatar pavelfatin avatar reitzig avatar rillig avatar serjsysoev avatar sparky983 avatar steanky avatar thijsiez avatar trespasserw avatar yanncebron avatar yole avatar zolotov avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

java-annotations's Issues

Java annotations causes NPE in Java Compiler

โฑ java -version
openjdk version "1.8.0-adoptopenjdk"
OpenJDK Runtime Environment (build 1.8.0-adoptopenjdk-jenkins_2018_05_19_01_00-b00)
OpenJDK 64-Bit Server VM (build 25.71-b00, mixed mode)

It looks like annotations triggers the https://bugs.java.com/bugdatabase/view_bug.do?bug_id=8210487 in JDK 1.8.

I have not been able to track down a reproducible test case, as the entire compile just goes kablooey.

Information:java: An exception has occurred in the compiler (1.8.0-adoptopenjdk). Please file a bug against the Java compiler via the Java bug reporting page (http://bugreport.java.com) after checking the Bug Database (http://bugs.java.com) for duplicates. Include your program and the following diagnostic in your report. Thank you.
Information:java: java.lang.NullPointerException
Information:java: 	at com.sun.tools.javac.code.Types.removeWildcards(Types.java:601)
Information:java: 	at com.sun.tools.javac.code.Types$DescriptorCache$FunctionDescriptor.getType(Types.java:362)
Information:java: 	at com.sun.tools.javac.code.Types.findDescriptorType(Types.java:568)
Information:java: 	at com.sun.tools.javac.code.Types.isFunctionalInterface(Types.java:585)
Information:java: 	at com.sun.tools.javac.comp.DeferredAttr$CheckStuckPolicy.visitLambda(DeferredAttr.java:997)
Information:java: 	at com.sun.tools.javac.comp.DeferredAttr$OverloadStuckPolicy.visitLambda(DeferredAttr.java:1080)
Information:java: 	at com.sun.tools.javac.tree.JCTree$JCLambda.accept(JCTree.java:1624)
Information:java: 	at com.sun.tools.javac.tree.TreeScanner.scan(TreeScanner.java:49)
Information:java: 	at com.sun.tools.javac.comp.DeferredAttr$FilterScanner.scan(DeferredAttr.java:913)
Information:java: 	at com.sun.tools.javac.comp.DeferredAttr$CheckStuckPolicy.<init>(DeferredAttr.java:980)
Information:java: 	at com.sun.tools.javac.comp.DeferredAttr$OverloadStuckPolicy.<init>(DeferredAttr.java:1075)
Information:java: 	at com.sun.tools.javac.comp.DeferredAttr$DeferredType.check(DeferredAttr.java:229)
Information:java: 	at com.sun.tools.javac.comp.Resolve$MethodResultInfo.check(Resolve.java:1008)
Information:java: 	at com.sun.tools.javac.comp.Resolve$4.checkArg(Resolve.java:835)
Information:java: 	at com.sun.tools.javac.comp.Resolve$AbstractMethodCheck.argumentsAcceptable(Resolve.java:735)
Information:java: 	at com.sun.tools.javac.comp.Resolve$4.argumentsAcceptable(Resolve.java:844)
Information:java: 	at com.sun.tools.javac.comp.Resolve.rawInstantiate(Resolve.java:579)
Information:java: 	at com.sun.tools.javac.comp.Resolve.selectBest(Resolve.java:1446)
Information:java: 	at com.sun.tools.javac.comp.Resolve.findMethodInScope(Resolve.java:1633)
Information:java: 	at com.sun.tools.javac.comp.Resolve.findMethod(Resolve.java:1704)
Information:java: 	at com.sun.tools.javac.comp.Resolve.findMethod(Resolve.java:1677)
Information:java: 	at com.sun.tools.javac.comp.Resolve.findConstructor(Resolve.java:2568)
Information:java: 	at com.sun.tools.javac.comp.Resolve$11.doLookup(Resolve.java:2537)
Information:java: 	at com.sun.tools.javac.comp.Resolve$BasicLookupHelper.lookup(Resolve.java:3097)
Information:java: 	at com.sun.tools.javac.comp.Resolve.lookupMethod(Resolve.java:3348)
Information:java: 	at com.sun.tools.javac.comp.Resolve.resolveConstructor(Resolve.java:2534)
Information:java: 	at com.sun.tools.javac.comp.Resolve.resolveConstructor(Resolve.java:2525)
Information:java: 	at com.sun.tools.javac.comp.Attr.visitNewClass(Attr.java:2079)
Information:java: 	at com.sun.tools.javac.tree.JCTree$JCNewClass.accept(JCTree.java:1516)
Information:java: 	at com.sun.tools.javac.comp.Attr.attribTree(Attr.java:576)
Information:java: 	at com.sun.tools.javac.comp.Attr.visitReturn(Attr.java:1686)
Information:java: 	at com.sun.tools.javac.tree.JCTree$JCReturn.accept(JCTree.java:1384)
Information:java: 	at com.sun.tools.javac.comp.Attr.attribStat(Attr.java:645)
Information:java: 	at com.sun.tools.javac.comp.Attr.attribStats(Attr.java:661)
Information:java: 	at com.sun.tools.javac.comp.Attr.visitBlock(Attr.java:1124)
Information:java: 	at com.sun.tools.javac.tree.JCTree$JCBlock.accept(JCTree.java:909)
Information:java: 	at com.sun.tools.javac.comp.Attr.visitMethodDef(Attr.java:1013)
Information:java: 	at com.sun.tools.javac.tree.JCTree$JCMethodDecl.accept(JCTree.java:778)
Information:java: 	at com.sun.tools.javac.comp.Attr.attribClassBody(Attr.java:4364)
Information:java: 	at com.sun.tools.javac.comp.Attr.attribClass(Attr.java:4272)
Information:java: 	at com.sun.tools.javac.comp.Attr.attribClass(Attr.java:4201)
Information:java: 	at com.sun.tools.javac.comp.Attr.visitClassDef(Attr.java:870)
Information:java: 	at com.sun.tools.javac.tree.JCTree$JCClassDecl.accept(JCTree.java:693)
Information:java: 	at com.sun.tools.javac.comp.Attr.attrib(Attr.java:4176)
Information:java: 	at com.sun.tools.javac.main.JavaCompiler.attribute(JavaCompiler.java:1248)
Information:java: 	at com.sun.tools.javac.main.JavaCompiler.compile2(JavaCompiler.java:901)
Information:java: 	at com.sun.tools.javac.main.JavaCompiler.compile(JavaCompiler.java:860)
Information:java: 	at com.sun.tools.javac.main.Main.compile(Main.java:523)
Information:java: 	at com.sun.tools.javac.api.JavacTaskImpl.doCall(JavacTaskImpl.java:129)
Information:java: 	at com.sun.tools.javac.api.JavacTaskImpl.call(JavacTaskImpl.java:138)
Information:java: 	at org.jetbrains.jps.javac.JavacMain.compile(JavacMain.java:193)
Information:java: 	at org.jetbrains.jps.incremental.java.JavaBuilder.compileJava(JavaBuilder.java:448)
Information:java: 	at org.jetbrains.jps.incremental.java.JavaBuilder.compile(JavaBuilder.java:318)
Information:java: 	at org.jetbrains.jps.incremental.java.JavaBuilder.doBuild(JavaBuilder.java:243)
Information:java: 	at org.jetbrains.jps.incremental.java.JavaBuilder.build(JavaBuilder.java:201)
Information:java: 	at org.jetbrains.jps.incremental.IncProjectBuilder.runModuleLevelBuilders(IncProjectBuilder.java:1317)
Information:java: 	at org.jetbrains.jps.incremental.IncProjectBuilder.runBuildersForChunk(IncProjectBuilder.java:993)
Information:java: 	at org.jetbrains.jps.incremental.IncProjectBuilder.buildTargetsChunk(IncProjectBuilder.java:1065)
Information:java: 	at org.jetbrains.jps.incremental.IncProjectBuilder.buildChunkIfAffected(IncProjectBuilder.java:956)
Information:java: 	at org.jetbrains.jps.incremental.IncProjectBuilder.buildChunks(IncProjectBuilder.java:788)
Information:java: 	at org.jetbrains.jps.incremental.IncProjectBuilder.runBuild(IncProjectBuilder.java:377)
Information:java: 	at org.jetbrains.jps.incremental.IncProjectBuilder.build(IncProjectBuilder.java:184)
Information:java: 	at org.jetbrains.jps.cmdline.BuildRunner.runBuild(BuildRunner.java:138)
Information:java: 	at org.jetbrains.jps.cmdline.BuildSession.runBuild(BuildSession.java:309)
Information:java: 	at org.jetbrains.jps.cmdline.BuildSession.run(BuildSession.java:137)
Information:java: 	at org.jetbrains.jps.cmdline.BuildMain$MyMessageHandler.lambda$channelRead0$0(BuildMain.java:235)
Information:java: 	at org.jetbrains.jps.service.impl.SharedThreadPoolImpl.lambda$executeOnPooledThread$0(SharedThreadPoolImpl.java:42)
Information:java: 	at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
Information:java: 	at java.util.concurrent.FutureTask.run(FutureTask.java:266)
Information:java: 	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
Information:java: 	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
Information:java: 	at java.lang.Thread.run(Thread.java:748)
Information:java: Errors occurred while compiling module 'securitybuilder'
Information:javac 1.8.0-adoptopenjdk was used to compile java sources
Information:10/10/18 10:24 AM - Compilation completed with 1 error and 0 warnings in 3 s 742 ms
Error:java: Compilation failed: internal java compiler error

@HiddenFromAutocomplete or the most useful missing low hanging fruit

Hi @JetBrains, there are many cases where a method has been superseded by another or simply exists for an implementationDetail reason.
E.g in Kotlin multiplatform in order to make lists much more interoperable between pure JS and Kotlin JVM code, I have to make an extension method on MutableLIst.addAllMPP() that only exists as an implementation detail, it is used in our Kotlin JS and JVM wrappers of arraylists but elsewhere we want developpers to only use the regular .addAll().
There is already the @deprecated annotation which put a strikethrough on the autocomplete result, but here we want to remove all noise and simply hides the method from autocomplete results, a basic filter.
Therefore it would be amazing if you could implement an identifier annotation @HiddenFromAutocomplete that the Kotlin plugin (and maybe the Java one) could leverage :)
On a more common case, it could be used for accelerating the reduction of use of the most evil deprecated or dangerous functions.

@amaembo friendly ping

[Feature Request] Is it possible add when field for @Nullable

Hello,

Is it possible add when field for @nullable annotation ?

IDE has already helped me if I miss null checks, but It would be even better If I understood when that null case happened.
That way, I can understand when those fields, methods can be null and it will be more informative ๐Ÿ™‚

Possible Usage:

public class Car {
   @Nullable(when = "Car is in maintenance'")
   private Engine engine;
}

When the pop-up appears if I miss null check, it can also state when it could be null ๐Ÿ™‚

ApiStatus and Debug should contain private throwing constructor

While class ApiStatus and Debug simply server a purpose of being a common namespace for multiple annotations and cannot be extended ...



... they still can be instantiated which should be explicitly prohibited by adding a private constructor throwing an exception.

I am ready to open a fixing PR.

Ability to hint proper parameter names for functional interfaces

I am (re)-using multiple common functional interfaces in my code, and the parameter names sometimes do not properly match the intent. For example DoubleUnaryOperator taking a double generically named operand.

I believe there could be an annotation hinting the IDE into using our own name

// What is currently suggested
Vec.ZERO.withX(operand -> operand * 5);
// With hint
Vec.ZERO.withX(x -> x * 5);

// Similar example using UnaryOperator
// What is currently suggested
itemBuilder.meta(itemMetaBuilder -> itemMetaBuilder);
// With hint
itemBuilder.meta(metaBuilder -> metaBuilder);

The alternative would be creating my own interfaces, which feels a bit unnecessary.

Add @OverridingMethodsMustInvokeSuper

The Java | Inheritance issues | Method does not call super method inspection produces a warning when a method overrides another method without calling the super method. By default, this is only done when the super method is annotated with javax.annotation.OverridingMethodsMustInvokeSuper. I think that is a nice feature. Unfortunately, this annotation is not part of the official API and cannot be accessed when the JPMS (aka. Jigsaw) is used. I would like to see a similar annotation within this annotation module.

Add an @Experimental annotation

Just had a small idea;
what about an @Experimental annotation for methods and fields which would let a user somehow know that the method they are trying to use is experimental and might not work correctly?

Please publish the official PGP keys so the releases can be verified

See https://youtrack.jetbrains.com/issue/KT-33781
See junit-team/junit5#2020

I get the following error when upgrading to 23.0:

Checksum/PGP violations detected on resolving configuration :src:core:compileClasspath
Trusted PGP keys for group org.jetbrains are [bcf4173966770193, 379ce192d401ab61],
however artifact is signed by [c2148900bcd3c2af] only:
org.jetbrains:annotations:23.0.0 (pgp=[c2148900bcd3c2af], sha512=[computation skipped])

Note: this is different from #62, and what I want is a reference of the official PGP key(s) on the project website (or at GitHub).

Alternative for Kotlin's `replaceWith`

It would be really nice to have an annotation, perhaps @ApiStatus.SuggestedAlternative, @ApiStatus.UseInstead or @ApiStatus.ReplaceWith that used the same internal logic as Kotlin's deprecation system to allow Java developers to provide alternatives to deprecated elements that can be picked up by an IDE.

Publish Range annotation

We have experimental Range annotation to specify the range of integral values. We may consider to publish it officially.

PropertyKey with compile time prefix value

Hello!

I'd like to use PropertyKey in some of my projects in order to control usages of l10n keys in compile time. The issue that I faced is that all my property keys is prefixed with "title" and "detail" values. So that when I create an object (that needs to be localized) I set only the error key without prefix. See the code below for clarification:

// imports omitted
public final class Error {
    private final String errorKey;
    public String getErrorKey() {
        return errorKey;
    }
    // would like to ability to set _prefix_ value(s)
    public Error(@PropertyKey(resourceBundle = "app", prefix={"title.", "detail."}) String errorKey) {
        this.errorKey = errorKey;
    }
}

public class ErrorHandler{
    // somewhere in errorHandler
    public void localizeError(Error error, ResourceBundle resourceBundle){
        // create prefixed keys
        String titleKey = "title." + error.getErrorKey();
        String detailKey = "detail." + error.getErrorKey();

        // localize the error
        String title = resourceBundle.getString(titleKey);
        String detail = resourceBundle.getString(detailKey);

        // print localized messages
        System.out.println("Localized error title is: " + title);
        System.out.println("Localized error detail is: " + detail);
    }
}

So, my questions are:

  1. Is it possible to get this functionality in the nearest feature? And could you suggest any workaround for now?
  2. Could I write my own annotation with such functionality? Probably in this case I'm supposed to enhance the IDEA inspections. I've never written customization (plugins or so) for IDEA and I'm afraid it would require a lot of work to implement my simple logic, isn't it?

@Contract on records

Add the target RECORD_COMPONENT to the Contract annotation to allow annotations on records.

Add @Covariant and @Contravariant annotations

As a library developer, I want to be able to add some annotations to mark the variance of the type parameters of a class. IDE can give the following hint based on this annotation:

  • Report a warning when contravariant type parameter T is used as a function parameter type
  • Report a warning when covariant type parameter T is used as a function return type
  • For function parameter types, prompt user to use Function<? extends T, ? super U> (take java.util.function.Function as an example) instead of Function<T, U>

And the jvm-based language can choose to understand this annotation (e.g. kotlin can understand class C<@Covariant T> as class C<out T>. This is convenient for developers to provide Kotlin-friendly APIs using pure Java.

Is it vaild for Kotlin?

I use @RegExp as the following pattern. But looks it not working.

fun f(@RegExp r: String){}

Remove redundant targets from Nullability-annotations

At current both @NotNull and @Nullable have quite broad scopes which commonly overlap:

@Target({ElementType.METHOD, ElementType.FIELD, ElementType.PARAMETER, ElementType.LOCAL_VARIABLE, ElementType.TYPE_USE})

@Target({ElementType.METHOD, ElementType.FIELD, ElementType.PARAMETER, ElementType.LOCAL_VARIABLE, ElementType.TYPE_USE})

While this is required for java5 (which obviously does not have ElementType.TYPE_USE) it is more of an issue rather than a feature on java 8+. I.e. overlapping scopes lead to tools such as Javadoc recognizing both targets as matched thus leading to issues such as duplication of the annotation in documentation in case of the latter.

Thus I suggest keeping only ElementType.TYPE_USE on these annotations in java8 version of the project, and keeping only {ElementType.METHOD, ElementType.FIELD, ElementType.PARAMETER, ElementType.LOCAL_VARIABLE} on java5 version.

If this gets approved I am ready to create the corresponding PR.

@CalledFromNative annotation

From https://youtrack.jetbrains.com/issue/IDEA-163737:

A very usefull annotation would be a @CalledFromNative that would be used to mark class methods that are meant to be called from native code. This annotation would allow for suppressing of the "method is never used" inspection and would in general help in clarifying the code. This would especially be useful in Android (Studio) projects that mix java and native code.

@Language should be applicable as a type-annotation.

Description

@Target ElementType.TYPE_USE may be added to @Language annotation to allow its usage in applicablecontexts.

Example

Currently the following example won't compile although it is logical:

private final @NotNull Map<@NotNull NamespacedKey, @Language("json") @NotNull String> addedAdvancements;

Another positive side is that while currently IntelliJ warns on incorrect order in the following case:

public void addAdvancement(final @NotNull NamespacedKey key,
                           final @Language("json") @NotNull String advancementJson) { /* ... */ }

suggesting swapping of final and @Language("json"), this wouldn't be true if TYPE_USE was present on the annotation.

@Immutable annotation for value classes

Hi!

I am currently migrating a projeect from jsr305 to java-annotations. One of the annotations I can't really seem to find an equivalent for is @Immutable. A class being @Immutable should not have setters and possibly not even non-final fields.

The original implementation and documentation:

/**
 * The class to which this annotation is applied is immutable. This means that
 * its state cannot be seen to change by callers. Of necessity this means that
 * all public fields are final, and that all public final reference fields refer
 * to other immutable objects, and that methods do not publish references to any
 * internal state which is mutable by implementation even if not by design.
 * Immutable objects may still have internal mutable state for purposes of
 * performance optimization; some state variables may be lazily computed, so
 * long as they are computed from immutable state and that callers cannot tell
 * the difference.
 * <p>
 * Immutable objects are inherently thread-safe; they may be passed between
 * threads or published without synchronization.
 */
@Documented
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.CLASS)
public @interface Immutable {
}

Unify the module names of java8 and java5 modules

Currently, java5 modules use different module name (org.jetbrains.annotations.java5).

This actually doesn't make any sense to the userโ€”โ€”jigswa module names are only used in Java 9 or later, and the same package can only belong to one module. Using a unified module name can reduce the user's troubles without any negative impact.

Code generation wrong for arrays annotated with @NotNull on elements

I'm not sure whether this here is the correct repo to report this.

The nullability checks generated on arrays seem to be wrong. Consider this code:

import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

class Foo {
    static void foo(@NotNull String @Nullable [] query) {
        if ( query == null ) {
            System.out.println("query null");
        } else {
            System.out.println(String.join(", ", query));
        }
    }

    static void bar(@Nullable String @NotNull [] query) {
        if ( query == null ) {
            System.out.println("query null");
        } else {
            System.out.println(String.join(", ", query));
        }
    }

    public static void main(String[] args) {
        Runnable[] tests = new Runnable[] {
                () -> { foo(new String[] {"a", "b", "c"}); },
                () -> { foo(new String[] {"a", null, "c"}); },
                () -> { foo(null); },
                () -> { bar(new String[] {"a", "b", "c"}); },
                () -> { bar(new String[] {"a", null, "c"}); },
                () -> { bar(null); }
        };

        for ( Runnable test : tests ) {
            try {
                test.run();
            } catch ( Exception e ) {
                System.err.println(e);
            }
        }
    }
}

Expected:

a, b, c
java.lang.IllegalArgumentException: <something along the lines of no element can be null>
query null
a, b, c
a, null, c
java.lang.IllegalArgumentException: Argument for @NotNull parameter 'query' of com/digithurst/hacc/sdk/Foo.bar must not be null

This is consistent with IDEA inspections:
image
image

Actual:

a, b, c
a, null, c
java.lang.IllegalArgumentException: Argument for @NotNull parameter 'query' of com/digithurst/hacc/sdk/Foo.foo must not be null
a, b, c
a, null, c
java.lang.IllegalArgumentException: Argument for @NotNull parameter 'query' of com/digithurst/hacc/sdk/Foo.bar must not be null

Observed with annotations 17.0.0, Java 8.0.181-oracle run from IDEA 2019.1 (directly and via Gradle 5.3.1).

Docs: @Nullable/@NotNull on a type declaration?

The documentation for @Nullable and @NotNull explicitly state the actions that these annotations apply to when used with methods, parameters, and variables/fields, but don't mention what it means when these annotations are used on a class.

An element annotated with Nullable claims null value is perfectly valid to return (for methods), pass to (parameters) or hold in (local variables and fields).

I tried annotating a class with @NotNull and @Nullable to see if IntelliJ's static analysis could provide hints about what's expected, but no warnings were generated for anything I did with it (beyond some "always-true" warnings for various combinations, but these were also generated without the class-level annotation). I've included the class below and documented my assumptions as a sanity-check.

I can think of two possible (likely) meanings:

  1. Variables, fields, parameters. and returns declared as the annotated type should default to the annotated nullability
  2. The fields, parameters, and/or return types within the annotated type should default to the annotated nullability

For the first option, I'm unsure what it would mean to apply @NotNull to a class given the strict constraints on using it with, for example, Map::get. There's no way a class can ever guarantee that it can or cannot be null everywhere it's used[*], since anyone can write MyClass myClass = null; (although that could generate a warning). However, if the strictness for using these annotations is more relaxed than with fields/methods/etc. and is more of a suggestion, then perhaps java.util.Optional should be annotated with @NotNull?

The second option also seems possible given my experience with other projects, but unlikely. Some class-level annotations are "distributed" into the class, such as Lombok's @Getter). However, I don't know of any annotation libraries that treat @Nullable/@NotNull this way, so I wouldn't assume that's how this annotation behaves. Plus, given the stance in #18, it seems this kind of functionality isn't desired (at least by JetBrains).

The official Javadoc for ElementType specifically mentions a hypothetical @NonNull annotation applied to a class via TYPE_USE, but I'm not clear on what it's trying to say.

The TYPE_USE constant includes class and interface declarations and type parameter declarations as a convenience for designers of type checkers which give semantics to annotation interfaces. For example, if the annotation interface NonNull is meta-annotated with @Target(ElementType.TYPE_USE), then @NonNull class C {...} could be treated by a type checker as indicating that all variables of class C are non-null, while still allowing variables of other classes to be non-null or not non-null based on whether @NonNull appears at the variable's declaration.

Does "variables of class C" refer to variables declared within class C, or variables with a type of C? I believe it's the latter, but IntelliJ's code analysis doesn't appear to use this information in this way (or at all).

In summary, what I'm requesting is:

  1. Clarification of which of the scenarios in the example should be influenced by a type-level nullity annotation (plus any obvious ones I missed)
  2. Updates to the documentation for @NotNull/@Nullable with the expected semantics (or lack thereof?) of annotating a type declaration with these annotations
  3. If any of the scenarios should be influenced, I'd like IntelliJ's static analysis updated to report them.

[*] Ignoring Project Valalla, but from my understanding we would already be able to detect that a class is inline without an annotation

Tested using Java 8 & 11 with IntelliJ Ultimate 2021.1.2:

import java.util.concurrent.ThreadLocalRandom;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

@NotNull
public class Example {
	private Integer field1;
	private int     field2;

	// Class-level @NotNull doesn't seem to influence fields, since this assignment doesn't produce a warning
	public void setField1(@Nullable Integer value) {
		this.field1 = value;
	}

	// Class-level @NotNull/@Nullable don't seem to influence method parameters, since this (questionably) doesn't
	// produce a warning with either class annotation, nor with an absent class-level annotation.
	public void setField2(Integer value) {
		this.field2 = value;
	}

	protected Boolean validate() {
		Integer value1 = this.field1;
		Integer value2 = this.field2;
		// This is included solely to prevent an unavoidable constant conditions warning on the return, since
		// field2 is a primitive. I'm avoiding a suppression comment so that other warnings can still appear.
		if (ThreadLocalRandom.current().nextBoolean()) {
			value2 = this.field1;
		}
		// Class-level @NotNull doesn't seem to influence method return types, since possibly returning null
		// here doesn't produce a warning when the class is annotated with @NotNull.
		return (value2 != null && value1 == null) ? null : true;
	}

	// Annotating the following method's parameter with @NotNull/@Nullable does not produce any warnings beyond
	// the null-check when the parameter is @NotNull, so a parameter of the annotated class's type doesn't appear
	// to default to the type's annotation, nor is a conflicting declaration considered invalid.

	// If nullity was expected to match the type's annotation, this would produce a warning if the parameter was
	// annotated with the opposite annotation.
	public static boolean validate(Example example) {
		// If parameter nullity was inherited from the parameter's type in the absence of an explicit
		// annotation this would produce a warning when the type was annotated @NotNull, even when
		// the parameter doesn't have an annotation
		if (example == null) {
			return false;
		}
		// Likewise, if the previous null check is removed and the class is annotated @Nullable, this would
		// produce a warning if nullity is inherited, but it does not, so @Nullable is also not inherited.
		Boolean value = example.validate();
		if (value == null) {
			return false;
		}
		return value;
	}

	// Annotating the following method's return type with @NotNull/@Nullable does not produce warnings beyond
	// returning null when the method is @NotNull, so a return type's nullity doesn't appear to default to the
	// type's annotation, nor is a conflicting declaration considered invalid.

	// If nullity was expected to match the class's annotation, this would produce a warning when the return
	// type was annotated the opposite annotation.
	public static Example create() {
		Example ex = new Example();
		if (ex.validate() == Boolean.TRUE) {
			return ex;
		}
		// If nullity for return types defaulted to the type's nullity, this would produce a warning when the
		// type was annotated @NotNull.
		return null;
	}
}

VisibleForTesting is missing

Hi team,
I'm surprised I haven't found this one raised before, maybe it's just my OCD or I am missing something.
@testonly is great, but is not enough I believe as a common (maybe not perfect) pattern is increasing visibility of a method to make it reachable for tests while it is still actually used in production.
You can argue that you shouldn't have such methods, but than there shouldn't be TestOnly methods either.
I believe we either need a new annotation only applying to visibility, or if it feels more natural add some property to the TestOnly to indicate that it only applies to visibility. Having said that I believe it'd be too verbose and is probably more restricting in future.
Maybe this has been discussed before and ruled out for some reason, I'd love to hear the reasoning, but I feed strongly that it is just missing and would be a great benefit if it existed.
Thank you,
Sergey

add missing changelog

Please maintain a changelog or, at least, provide some documentation about latest changes. Latest version is 16.0.3 on GitHub and 19.0.0 on Maven Central, but we have no information about changes, bug fixed, etc.

Java9 module name

It would be great if you could publish this artifact with a proper module name like org.jetbrains.annotations

Annotations are shown multiple time in javadocs

I'm using this dependency:

<dependency>
    <groupId>org.jetbrains</groupId>
    <artifactId>annotations</artifactId>
    <version>20.1.0</version>
</dependency>

With this maven plugin:

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-javadoc-plugin</artifactId>
    <version>3.2.0</version>
    <executions>
        <execution>
            <id>attach-javadocs</id>
            <phase>deploy</phase>
            <configuration>
                <quiet>true</quiet>
                <notimestamp>true</notimestamp>
                <encoding>${utf.encoding}</encoding> <!-- utf.encoding = UTF-8 -->
                <docencoding>${utf.encoding}</docencoding>
                <charset>${utf.encoding}</charset>
                <additionalOptions>
                    <additionalOption>-XDignore.symbol.file</additionalOption>
                    <additionalOption>-Xdoclint:-html</additionalOption>
                </additionalOptions>
                <linksource>true</linksource>
                <source>${java.version}</source> <!-- java.version = 11 -->
            </configuration>
            <goals>
                <goal>jar</goal>
            </goals>
        </execution>
    </executions>
</plugin>

When I now create a Javadoc of a class that contains e. g. NotNull or Nullable it results looks like this in the JavaDocs:

All methods overview:
image
image

Method detail:
image
image

I've also switched to another annotation library (jsr305) from that these annotations are only shown once.

Request annotation for instance methods that return "this" or some instance of the type of "this"

I'm requesting an annotation, I'll call it @ThisType, that can be attached to the return type of an instance method declared to return the type of the class containing the method definition.

For example:

abstract class Animal {
    public abstract @ThisType Animal copy();
}

I intend this annotation to have this effect on the IDE:
If an overriding method is created in a subclass, the return type is set to the subclass type.

For example, if I create a subclass Dog and use the Override Methods... action to override this method, the method that is created is:

@Override
public @ThisType Dog copy() {
    return null;
}

It would also be useful to have a quick way to override all of the @ThisType methods.

This feature would make implementing fluent APIs with subclasses a bit easier.

Please add missing documentation/rationale

I read through the README, and I can not find one line that says why I should use this project. What's the purpose? This needs to be clarified, preferably with at least one example.

On top of that, IntelliJ disturbs me in my work process with a pop up message indicating that not attaching these annotations (whatever "attaching" means, but I suppose, it will add a dependency in my build file) will sort of cloak away "issues".

So that's like two errors, although granted, the latter should be an issue filed somewhere else.

But one must wonder, did you simply expect that people click on "attach" buttons without any knowledge what these added dependencies actually do? I mean, it seems to even be hard to google this information. I didn't succeed. Hey, maybe that is what developers do these days and it's just me trying to keep my project not locked in to a particular IDE and actively trying to minimize the number of dependencies (and thus, complexity) in my project.

I am sure this - as well as some ten thousand more libraries and frameworks and "analyzers" that could be added as a dependency - has some perceived value to it. But it must be explained or else I feel like the whole world has gone batshit crazy to be honest. LOL! =)

Union and intersection annotations

Union:

@Union(Int::class, String::class)
fun foo() = if (Random.nextBoolean()) 1 else "1"

Intersection:

interface Foo
interface Bar
@Intersection(Foo::class, Bar::class)
fun foo(): Any = object : Foo, Bar { }

Contract solution for a method always returning the same for same arguments

I'd love to have a way of defining with a Contract that a method always returns the same instance of the same parameters, something like this:

@Contract(equalResults = true)
public FileConfiguration getConfig(String configName) {
    //...

The inspiration for this was this discussion: burdoto/e2uClaim#1 (comment)

This contract should then result in a warning that informs the user that repetitively calling the method for same arguments is unnecessary and the result can be stored in a local variable.

This is useful because like in this special case, a #getConfig(String) method may always return the same configuration for the same string parameter, while e. G. InputStream#read(int) does not always return the same on equal calls.
Now, I know this example is a bit niche, so it might even be best to assume @Contract(equalResults = true) for most methods. Let's discuss this idea.

PropertyKey is not working for RessourceBundle

When i add a new properties file to my project inside resources and name it as for example "lang1" than the BUNDLE_NAME is recognized correctly.

But if i add an ResourceBundle containing lang2_de and lang2_en and try to use its base name as BUNDLE_NAME it shows me the following error "Invalid resource bundle reference 'lang2'.

So i basically have 3 files.

lang1_de.properties
lang2_de.properties
lang2_en.properties

lang2 is bundled into an Resource Bundle with "'base name' = lang2"

This is working:

private const val BUNDLE_NAME = "lang1"

fun foo(@PropertyKey(resourceBundle = BUNDLE_NAME) key: String): String {
    return key
}

This is not:

private const val BUNDLE_NAME = "lang2"

fun foo(@PropertyKey(resourceBundle = BUNDLE_NAME) key: String): String {
    return key
}

But if i do the same thing with java it is working ...

private static final String BUNDLE_NAME = "lang2";

public static void foo(@PropertyKey(resourceBundle = BUNDLE_NAME) String key) {
    return key;
}

I am doing this for getting the information about my properties being used inside my code.

The properties are marked correctly inside the property files for both examples.

But for lang2 the strings used inside the code are all shown with inspection error "String literal 'testprop' doesn't appear to be valid property key ..."

Also see my issue at stackoverflow:
https://stackoverflow.com/questions/55915462/propertykey-cant-handle-resource-bundles

Consider removal of JdkConstants

The project currently has a requires directive for java.desktop in module-info due to the usage of AWT/Swing classes:

/**
* @deprecated this class will be removed in future versions to avoid Swing dependency,
* which is unnecessary for most of the clients. No IDE or static analysis tool should know
* about this class directly, as it creates new annotations using meta-annotations.
* If it's used in your project, please create similar annotations in your project directly.
*/
@Deprecated

Advanced @Contract capabilities

I was thinking about possible extra possibilities for the Contract annotation.
I have this example already; I will add more as I stumble upon them:
Consider this method:

    @Contract("CacheReference -> param1; null -> fail; !null -> new")
    protected abstract CacheReference<K, V> advanceIntoCacheRef(Reference<V> reference);

The method should do the following things; as described by the contract:

  • Throw an NPE, if the parameter is null
  • Wrap the parameter Reference (if not instanceof CacheReference, else see next) into a CacheReference
  • Return first parameter if the first parameter is instanceof CacheReference (which is already imported due to return type; return types should be validated by paramN)

Now, obviously this contract won't work, because it doesn't know about more things than nulls; really. Given other capabilities of IntelliJ, it should be fairly easy coming up with a simple, standalone concept for advanced Contract syntax.

Improvement: Provide a Java Module distribution for JetBrains annotations on Maven Central

I greatly appreciate that the annotations package is providing an Automatic-Module-Name definition.
The current version of JDK 16 still create warnings when using an automatic module with statements such as
requires static transitive org.jetbrains.annotations;

Java 9 was released in September 2017 and JDK 17 is around the corner.
I would assume it is time that JetBrains as a leading technology company finally release an annotation package which really supports the Java module concept in maven central.

You have already the module-info.java file, you just need to release a version containing it on Maven Central. And it is really time, Java 11 and Java 17 are LTS versions.

I am trying to move my java applications to a modular structure and I have to invest quite an effort to find a way around various packages still created for JDK 9-- meaning for DK versions older than 4 years.

Sincerely

Add @NotNullByDefault annotation

It's badly needed. Since years, I have a strict NotNull policy in all of my code, so I simply annotate the whole package. Everyone knows this policy is intact, it's just about telling the IDE as well. If I annotate my NotNull code with NotNull, whenever NotNull is appropriate, my NotNull code basically consists of only NotNull with some occasional actual NotNull code between all the NotNull annotations from time to time. :)

Currently, I fix this by mixing with Eclipse's NonNullByDefault (unfortunately, Eclipse's NonNull and Nullable aren't applicable to methods, fields and parameters (Target({ElementType.TYPE_USE})), so I have to use JetBrains annotations for this).

The new annotation should be applicable to packages and classes, maybe also methods. I personally don't care about using it in types, but other people's mileage may vary. Specifying to what elements exactly it applies (methods, fields and/or parameters, maybe also type use) isn't strictly necessary for me, but probably makes sense. I'd suggest to default to all of them or no default at all.

This would also cover #18.

Allow `@Language("regexp") CharSequence regex`

Where should report (if not here) that IntelliJ IDEA reports an error when using

@Language("regexp") CharSequence regex

while there are libraries (like AssertJ) that allow specifying regexps as CharSequences for convenience? My request is thus to allow @language annotations for CharSequence type variables in addition to String.

Convert to Kotlin

It would be good if this library was converted to Kotlin such that it could be used with Kotlin/common, Kotlin/JS and Kotlin/native.

I wouldn't mind doing this.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.