All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.google.gwt.reflect.client.strategy.GwtRetention Maven / Gradle / Ivy

The newest version!
package com.google.gwt.reflect.client.strategy;

import static java.lang.annotation.ElementType.CONSTRUCTOR;
import static java.lang.annotation.ElementType.FIELD;
import static java.lang.annotation.ElementType.METHOD;

import java.lang.annotation.Documented;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

import com.google.gwt.reflect.shared.GwtReflect;

/**
 * Use this annotations on your types and members to refine your
 * runtime reflection retention strategy.
 * 

* This annotation allows you to do two things:
* {@link #asyncOnly()} tells the gwt compiler that the annotated * type or member should only be loaded in the classloader-only split point.
* {@link #dependencies()} tells the compiler to include external dependencies * whenever the given type or member is included. *

* This gives you the power to defer code bloat into one big ball of code * that will not affect your application bootsrap timing. It also allows you * to declare reflection retention on classes you do not control, * so you don't have to have an unmaintainable mess of copies of source code * just to add your reflection retention annotations. *

* When you annotate a member (method, field or constructor), it's dependencies * will be added when that member is included (currently when the class is loaded, * but work is being done for more fine-grained inclusion). * If the member is deferred to the com.google.gwt.reflect.client.ConstPool split point, * so are its dependencies. If loaded synchronously ({@link #asyncOnly()}=false), * it is included when the enclosing type is sent through {@link GwtReflect#magicClass(Class)}, * or when you directly access that member as a CONSTANT-ONLY reference: *
* SomeClass.class.getField("constantName");// includes dependencies on that field * SomeClass.class.getMethod("constantName", CONSTANT_CLASS_ARRAY);// array must be a constant field. * SomeClass.class.getDeclaredMethods();// includes all dependencies of all declared methods. *

* Support for the full level of declared optimizations is not yet * complete, but this annotation will be used to define more * complex strategies for retaining reflective access to runtime types and members. *

* With great power comes great responsibility: Misuse of Retention policies may * lead to code bloat, and cause your application more code than is necessary * to perform its given duty. *

* That said, this does give you the power to directly control what code gets * loaded where, so if you know you want to include a given snippet of * code in a given code split, this will allow you to specify members you * want to include now, but call later on. *

* If you need to pull code of non-exclusive or leftover code blocks, * this annotation will allow you to pull specific code into an exclusive * code block, and reduce clinits() in your non-exclusive code blocks. * * @author james.nelson * */ @Documented @Target({CONSTRUCTOR, METHOD, FIELD}) @Retention(RetentionPolicy.CLASS) public @interface GwtRetention { final int PUBLIC = 1, PRIVATE = 2, PROTECTED = 4, PACKAGE = 8, ALL = PRIVATE | PROTECTED | PUBLIC | PACKAGE; /** * An int register of the privacy level of members to keep. *

* Use this to filter out unneeded members and reduce code size.
* Set to 0 to elide members. *

* This will allow you to do strange things, like only keep public and private; * really, whatever filter you want to reduce your compile size (just be careful!) * */ int privacy() default ALL; /** * This element will only be included in the monolithic ClassLoader. *

* This will allow you to defer things you "want later", and only * include what you need now behind a call to * {@link GwtReflect#getClassloader(com.google.gwt.user.client.rpc.AsyncCallback)}. *

* Future work is planned to build a preprocessor which checks against unused reflection * objects, and pulls those references out of the main application, and into the classloader. *

* In anticipation of this optimization, do try to prefer the "most constant possible" * manner of retrieving your reflection data. *

* BEST: SomeClass.class.getMethod("someConstantString", String.class, int[].class);
* GOOD: SomeClass.class.getMethod(SOME_CONSTANT_STRING, SOME_CONSTANT_CLASS_ARRAY);
* OKAY: Class c = GwtReflect.magicClass(SomeClass.class); c.getMethod(...);
* BAD: Method[] methods = GwtReflect.magicClass(SomeClass.class).getMethods();
* WORST: for (Method method : GwtReflect.magicClass(SomeClass.class).getMethods())
* if (isMethodIWant(method)) doSomething(method); *

* In order for this to work right, we will have to scan your ast for all calls * into reflection methods, and pull out anything unused into the classloader code block. * If we are unable to determine a minimum bounds for data needed in a class, * we will have to include it all immediately. *

* Any element which explicitly uses classLoaderOnly() will always be deferred, * and you should get in the habit of explicitly declaring this, * as it will make scanning either easier, or entirely unnecessary. *

* Once the deferment optimization is complete, a maven mojo will be provided * that can simply scan your gwt module, ignore all existing @GwtRetention annotations, * and auto annotate all elements with the most optimal retention levels possible. * * @return true to defer the annotation method, field, constructor or parameter */ boolean asyncOnly() default false; /** * This option is only valid when {@link GwtRetention} is placed inside * a class or package level {@link ReflectionStrategy}. *

* It tells the compiler whether or not to search super types for * public members of the given member type. *

* This defaults to true so out-of-the-box behavior matches * that of JVM reflection. You may want to set it to false to reduce code size; * just remember to always access members by their declaring class), */ boolean keepPublicSuperMembers() default true; /** * If you want to keep your parameter annotations, you must set this member to true *

* If it is a common request to keep complete jvm parity, * this default might change, so there is no harm in explicitly setting it * to false when you are trimming code bloat. * */ int annotationRetention() default ReflectionStrategy.RUNTIME; /** * If you want to keep your parameter annotations, you must set this member to true *

* If it is a common request to keep complete jvm parity, * this default might change, so there is no harm in explicitly setting it * to false when you are trimming code bloat. * */ boolean keepParameterAnnotations() default false; /** * Any additional dependencies to declare? *

* Add them to a GwtRetention annotation, and instead of explicitly * overriding and maintaining a copy of classes you don't control, * just add @Dependencies to a type you do control, and use it * to declare when and where you want to include the given dependency. *

* Be sure to read the doc on {@link GwtRetention} to see the * best practices for using this somewhat dangerous tool. *

* If you are using complex retention strategies, * you should run emma (and story-of-your-compile) to check your code coverage * and see if you can refine your strategy to keep code bloat down. *

* * * @return - An array of descriptors of other types to keep along with the * annotated retention member. */ Dependency[] dependencies() default {}; }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy