Annotation Type Keep


  • @Target({METHOD,FIELD,CONSTRUCTOR})
    public @interface Keep
    Denotes that the element should not be removed when the code is optimized by the tool kit.

    The tool kit removes unused methods during the optimization phase. If a struct appears in the signature of an @External method, necessary constructor, getters and setters for the struct survive the optimization phase even if the methods are not accessed in user code. More specifically, if a class is a writable struct and the class is used as a parameter type of an external method, its zero argument constructor (if it is defined) and property setters are not removed. Also, a class is a readable struct and the class is used as a return type of an external method, its getters are not removed. For example, in the following contract, @Keep annotation is not necessary for Person class since it is used as a parameter of an external method.

          // Person.java
          public class Person {
              public Person() {...}
              public String getName() {...}
              public void setName(String name) {...}
          }
    
          // Callee.java
          public class Score {
              @External
              public void hello(Person person) {
                  Context.println("Hello " + person.getName());
              }
          }
      

    There are some cases that a user must manually use @Keep annotation. When a struct is passed as an argument of Context.call(java.lang.Class<T>, java.math.BigInteger, score.Address, java.lang.String, java.lang.Object...), getters are called by system. Also, when a struct is returned by Context.call(java.lang.Class<T>, java.math.BigInteger, score.Address, java.lang.String, java.lang.Object...), a constructor and setters are called by system. However, the tool kit cannot track the runtime type of the parameter of the Context.call(java.lang.Class<T>, java.math.BigInteger, score.Address, java.lang.String, java.lang.Object...) method. Thus, the getters or setters are removed if they are not accessed in user code and they are not used as a parameter type or a return type of an external method. In that case, @Keep annotation is required for the necessary methods not to be optimized away. For example, in the following contract, @Keep annotation is necessary for getName because user code do not call the method and the Person class is not used as a parameter or a return type of an @External method.

          // Person.java
          class Person {
              public Person(name String) {...}
    
              @Keep
              public String getName() {...}
          }
    
          // Caller.java
          public class Caller {
              @External
              public void test(Address addr) {
                  Context.call(addr, "hello", new Person("Kim"));
              }
          }
      

    For the definition of readable struct and writable struct, refer to the document of @External

    See Also:
    External